そして再びMVC

ハブロコミュニティにこんにちは。

かつて私は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そして、はい-最も重要なこと。 リソースを使用して作成された小さなリソースの実例はリンクです。 このサービスを使用すると、カテゴリへのリンクをオンラインで保存できます。 既存のリポジトリは多くの理由で適切ではないため、それ自体が記述されています。 さらに、何かでカーネルをテストする必要がありました。

Source: https://habr.com/ru/post/J127798/


All Articles