かつて私はhabr リンクから記事に出会いました。 そのシステムを試してみたところ、多くの欠点があり、元の記事の翻訳が完全には存在しないという結論に達しました。 はい、この記事は時代遅れですが、同時に、シンプルで中規模のサイトを作成するための独自の小さなフレームワークを作成したかったのです。 私は2〜3メガバイトの名刺Webサイトを作成するための本格的なフレームワークを使用しているので、それを犠牲にすると考えています(常にではありませんが)。
一般に、目立った欠陥を修正し、結果をhabrozhitelamiと共有することにしました。
それで、何が改善されましたか?
1. Registryクラスの使用を取り除きます。 PHP5に__setや__getのような素晴らしいメソッドがあるのに、なぜ必要なのでしょうか?
2. PDOの代わりに、Active Recordsと呼ばれるクラスを作成しました。これにより、レイヤーを介してデータベースと通信できます。 コードの品質はそれほど高くなく、リファクタリングする必要があるため、ソースコードは提供しません。 ただし、必要に応じて追加します。
3. Templateクラスが少し書き直され、ネストされたテンプレートを作成する機能が追加されました。 これは次のようになります。
<?php
クラステンプレート{
private $ vars = array ( ) ;
関数 __set ( $ varname 、 $ value ) {
$ this- > vars [ $ varname ] = $ value ;
trueを 返し ます 。
}
function show ( $ name 、 $ data = false 、 $ display = true ) {
$ path = site_path 。 「ビュー」 。 DIRSEP $ name 。 '.php' ;
if ( ! file_exists ( $ path ) ) {
trigger_error ( 'Template `` 。 $ name 。 ' 'does not exist。' 、 E_USER_NOTICE ) ;
falseを 返し ます 。
}
if ( $ data ) {
//データを入力します
if ( is_array ( $ data ) ) {
foreach ( $ data as $ key => $ value ) {
$ this- > __set ( $ key 、 $ value ) ;
}
}
}
抽出 ( $ this- > vars ) ;
if ( $ display ) {
include ( $パス ) ;
} else {
if ( is_file ( $ path ) ) {
ob_start ( ) ;
インクルード $パス ;
$ contents = ob_get_contents ( ) ;
ob_end_clean ( ) ;
$コンテンツを 返し ます。
}
falseを 返し ます 。
}
}
}
?>
4.ルーターが変更され、URLのいくつかのパラメーターのサポートが登場しました。 ルーターにはまだ問題があると思われますが、これは時間の経過とともに解消されます。 しかし、それが動作している間:)
<?php
クラスルーター{
パブリック $パス ;
private $ args = array ( ) ;
関数 setPath ( $ path ) {
$ path = trim ( $ path 、 '/ \\' ) ;
$パス 。= DIRSEP ;
if ( ! is_dir ( $ path ) ) {
新しい例外をスロー( '無効なコントローラーパス: ``' 。 $ path 。 '' ' ) ;
}
$ this- > path = $ path ;
}
関数デリゲート( ) {
//パスを分析します
$ this- > getController ( $ file 、 $ controller 、 $ action 、 $ args ) ;
//ファイルは利用可能ですか?
if ( ! is_readable ( $ file ) ) {
trigger_error ( 'File `` 。 $ file 。 ' 'not found' 、 E_USER_ERROR ) ;
}
include ( $ファイル ) ;
//コントローラを作成します
$ class = 'Controller_' 。 $コントローラー ;
$コントローラー = 新しい $クラス ( ) ;
//アクションはオブジェクトで利用可能ですか?
if ( ! is_callable ( array ( $ controller 、 $ action ) ) )) {
trigger_error ( 'メソッドがありません `` 。 $ action 。 ' 'クラスで見つかりました' 、 E_USER_ERROR ) ;
}
//アクションを呼び出す
call_user_func_array ( array ( $ controller 、 $ action ) 、 $ args ) ;
}
private function getController ( & $ file 、 & $ controller 、 & $ action 、 & $ args ) {
$ route = ( empty ( $ _GET [ 'route' ] ) ) ? 'インデックス' : $ _GET [ 'route' ] ;
// urlと呼ばれる分割
$ route = trim ( $ route 、 '/ \\' ) ;
$ parts = explode ( '/' 、 $ route ) ;
//適切なコントローラーを見つける
$ cmd_path = $ this- > path ;
//デフォルトのコントローラー名を設定します(別のコントローラー名が見つかった場合は置き換えられます)
$コントローラー = 'インデックス' ;
foreach ( $ parts as $ part ) {
$ fullpath = $ cmd_path 。 $ part ;
// dirですか?
if ( is_dir ( $ fullpath ) ) {
$ cmd_path 。= $ part 。 DIRSEP ;
array_shift ( $パーツ ) ;
続ける ;
}
//ファイルですか?
if ( is_file ( $ fullpath 。 '.php' ) )) {
$コントローラー = $ part ;
array_shift ( $パーツ ) ;
休憩 ;
}
}
//コントローラのアクションメソッドを取得します
$ action = ( isset ( $ parts [ 0 ] ) && ! is_numeric ( $ parts [ 0 ] ) ) ? array_shift ( $ parts ) : 'インデックス' ;
$ file = $ cmd_path 。 $コントローラー 。 '.php' ;
$ args = $ parts ;
}
}
?>
5.モデル(実装済み)、ライブラリ(実装済み)がロードされるLoaderクラスが追加されました。 将来的には、そこにねじ込んで、ヘルパーをロードします。
<?php
クラスローダー{
パブリック $インスタンス ;
public $ vars = array ( ) ;
関数 __construct ( $ parent ) {
$ this- > instance = $ parent ;
}
関数モデル( $ model_name ) {
$ filename = strtolower ( $ model_name ) 。 '.php' ;
$ file = site_path 。 'models' 。 DIRSEP $ファイル名 ;
if ( ! file_exists ( $ file ) ) {
falseを 返し ます 。
}
include ( $ファイル ) ;
$ this- > instance- > $ model_name = new $ model_name ( new ActiveRecords ( ) ) ;
}
関数ライブラリ( $ name ) {
$ filename = strtolower ( $ name ) 。 '.php' ;
$ file = site_path 。 'ライブラリ' DIRSEP $ファイル名 ;
if ( ! file_exists ( $ file ) ) {
falseを 返し ます 。
}
include ( $ファイル ) ;
$ this- > instance- > $ name = new $ name ( new ActiveRecords ( ) ) ;
}
}
?>
ここで、ご覧のとおり、前述のActiveRecordsクラス(現在はシングルトーン)が任意のモデルまたはライブラリに渡されます。 このため、データベースとの連携はモデルとライブラリで利用可能になりつつあります(MVCコンセプトから期待されています)。 ただし、モデルとライブラリの名前には制限があります。たとえば、loadと呼ばれるモデルを使用することはできません。
モデル自体の基本クラスは、プロジェクトのすべての後続クラスの継承元であり、次のようになります。
<?php
クラス Model {
var $ db ;
関数 __construct ( $ db ) {
$ this- > db = $ db ;
}
}
?>
6.上記の変更を考慮すると、以降のすべてのコントローラーが継承されるコントローラーの基本クラスは、次のようになります。
<?php
class Controller_Base {
パブリック $テンプレート ;
パブリック $ロード ;
関数 __construct ( ) {
$ this- > template = new Template ( ) ;
$ this- > load = new loader ( $ this ) ;
}
関数 __set ( $ varname 、 $ value ) {
$ this- > $ varname = $ value ;
trueを 返し ます 。
}
}
?>
したがって、各コントローラーでは、LoaderクラスとTemplateクラスを使用できます。 そして、同様のことをコードで書くことができます:
$ this- > load- > model ( 'links' ) ;
$ this- > links- > add ( ' new ' ) ;
つまり、このタイプではモデルのすべてのメソッドが使用可能になります。
$ this- > [モデル名] -> [モデルのメソッド名]
7.また、小さな変更がスタートアップスクリプトに追加されました-セッションの初期化(将来、データベースからセッションを追加する予定です)、頻繁に使用されるリダイレクト関数が__autoload関数と共に追加されます。
関数リダイレクト( $ url )
{
ヘッダー ( "Location:" 。 $ Url ) ;
}
データベースに接続するだけでなく(ここではわかりませんが、Active Recordsクラスでデータベースに接続するのは理にかなっていますか?)
8.そして最も重要なことは、すべてのリクエストを処理するメインのindex.phpファイルです。 これは次のようになります。
<?php
require 'includes / start.php' ;
$ router = new Router ( ) ;
$ router- > setPath ( site_path 。 'controllers' ) ;
$ router- > delegate ( ) ;
?>
フレームワークのソースコードはこちらからダウンロードできます: link ここで、ソースコードがすぐに使用できるわけではないことに注意してください。 使用例として必要な、ベースカーネルに加えて、いくつかのコードのみを考えます。
あなたのコメント、発言、指示に喜んでいます。
PSそして、はい-最も重要なこと。 リソースを使用して作成された小さなリソースの実例はリンクです。 このサービスを使用すると、カテゴリへのリンクをオンラインで保存できます。 既存のリポジトリは多くの理由で適切ではないため、それ自体が記述されています。 さらに、何かでカーネルをテストする必要がありました。