以前にジャンプとリクエストの転送の実装方法について説明しました。もちろん、これは単なる概要であり、より詳細な内容については、特定のフレームワークの実装を自分で読む必要があります。
ジャンプと転送が利用できるようになったので、後でモデルの作成に戻ることができます。まず、以前の実装は非常に醜いものでした。
1 | $viewPath = dirname(__FILE__) . '/../views/index.php'; |
2 | if(file_exists($viewPath)) { |
3 | include $viewPath; |
4 | } else { |
5 | echo 'view does not exists'; |
if(file_exists($viewPath)) {
6 | } |
3
01 |
4
02 | class TestController extends Controller { |
03 | public function test() { |
04 | $this->_assign(array( |
05 | 'arr' => array( |
06 | 'test','test2' |
07 | ), |
08 | 'str' => 'it is a str' |
09 | )); |
10 | $this->_display('test'); |
11 | } |
12 | } |
これは私が今日書いた後の呼び出し方法です。smarty を学習したことがある方なら、これが Smarty に非常に似ていることがわかるでしょう。実際、私も toper を書いたときに、smarty の影響を受けました。感想 ビューはsmartyを使いましたが、自作フレームワークということもあり、ビューは全て自分で書かないといけないので、それでも後からでも使えるようにしておきました。構成ファイルを変更することで、フレームワーク自体の実装を使用せずにビューを Smarty に切り替えることができます。
まず、コードを簡素化するために、実際の実装は誰でも理解できるように単純化しました。フレームワークはさらに複雑になります。
最初に代入します。その機能は変数に値を代入することです。ここでは、渡されるパラメーターはすべて HashTable と呼ばれるものであると仮定します。代入方法は、直接呼び出す必要はありません。このインターフェースを実装するための値:
1 | protected function _assign(Array $arr) { |
2 | View::assign($arr); |
3 | } |
ビューのデータの保存と表示を処理するために、View.php ファイルを定義しました。もちろん、View::assign メソッドは実装された関数の 1 つです。 。 。
View.php ではどのように実装されますか?
1 | private static $_data = array(); |
2 | public static function assign($arr) { |
プライベート static $_data = array();
3 | foreach($arr as $key => $val) { |
4 | if(!is_int($key)) { |
2
5 | //过滤掉如array('test','test2')这种数据 |
6 | self::$_data[$key] = $val; |
7 | } |
8 | } |
9 | } |
assign は静的メソッドであり、データをこのクラスに格納する必要があるため、静的メンバー変数 $_data を定義する必要があります。この変数には、コントローラーによって渡されたデータが格納されます。型ヒントは以前にコントローラーの assign で実行されていたため、View の assign によって渡される仮パラメーターはすべて配列であることが保証されます。必要なのは foreach だけであり、それらを順番に格納するので、self を使用しないのはなぜでしょうか。 ::$ を直接指定すると、文が 1 つしかないので、_data = $arr はどうでしょうか?
まず、配列内のデータの一部が間違っている可能性があります。たとえば、array('test','test2') のデータ test と test2 が何を表しているのかわかりません。要件がより厳しい場合は、ユーザーに直接警告することもできます。
第 2 に、ユーザーが assign を複数回呼び出す可能性があります。参照が直接使用されると、2 回目の assign 呼び出しで最初のデータが失われるため、これは許容できません。
割り当ては完了しました。次に、それをどのように表示するかという問題があります。コントローラーでは、内部実装を担当せず、インターフェイスを直接呼び出す方が良いですが、特定の書式設定が必要です。インターフェースを呼び出す前に行う必要があります:
01 | protected function _display($str) { |
02 | if(is_string($str)) { |
保護された関数 _display($str) {
03 | $str = str_replace(array( |
04 | '.','#' |
02
05 | ),array( |
06 | '/','.' |
07 | ),$str); |
08 | View::display(MODULES_PATH . View::VIEW_BASE_PATH . $str . '.php'); |
09 | } |
10 | } |
見た目の美しさやその他の XXX の理由から、実際のパラメータとして渡されるときは / を表すパスを変更できます。test/test2.php が呼び出されると、test に渡すだけで済みます。 .test2.php で十分です。もちろん、これには問題もあります。先ほどの例のように、test.test2.php が実際には test/test2/php に解析されるため、これをどのように解決するかが問題になります。 # を使用して表すので、渡されると test.test2#php になります。もう 1 つ問題があります。.php は基本的にすべてのページに存在するのに、なぜそれを渡す必要があるのでしょうか? フレームワークはそれを直接追加するだけなので、ユーザーは test.test2 を入力するだけなので、論理的には簡単です。テストモジュールの下のビューファイルtest2を理解するために。 thinkphp を使用したことがある人なら、これがその書き方に非常に似ていることがわかると思います。実際、私が書き始めたとき、thinkphp のソースコードを読みながら書いたので、多くの点でそのアイデアを借用しました。私は個人的に # を使用するのが嫌いなので、基本的にビュー ファイルでは # を使用しません。test.view.php のような意味のないファイル名を記述するのはそれほど退屈ではないと思うからです。PHP を直接テストするだけで十分です。一種の名前フレームワークは問題の一部を解決するのに役立つため、この問題は基本的に存在しません。
定数 View::VIEW_BASE_PATH もあります。この定数はビューのルート ディレクトリへのパスを表すため、実際に渡されるのは実際の絶対パスです。
display はこのビューファイルを表示するため、必ず特定のファイルを使用します。具体的な実装は次のとおりです。
1
1 | public static function display($file) { |
パブリック静的関数表示($file) {
2 | if(file_exists($file)) { |
3 | extract(self::$_data); |
2
4 | include $file; |
5 | } else { |
6 | throw new ViewException(ViewException::NOT_EXISTS_TEMPLATE); |
7 | } |
8 | } |
抽出は配列の分割に関するものです。詳細については、PHP マニュアルを参照してください。
ビューファイルが存在しない可能性があるため、それを判断する必要があります。ビューファイルが存在しない場合、例外は ViewException を使用しており、このクラスは新しく定義されていることに注意してください。このパラメータは、ビュー テンプレートが存在しないためにこの例外が発生することを示します。
次に、この例外クラスの具体的な実装を見てみましょう:
01 |
02 | class ViewException extends BaseException { |
03 | const NOT_EXISTS_TEMPLATE = 1; |
04 | public function __construct($code = 0) { |
02
05 | switch($code) { |
06 | case ViewException::NOT_EXISTS_TEMPLATE: |
07 | $msg = 'the template file is not exists'; |
08 | break; |
09 | default : |
10 | $msg = 'unknown exception'; |
11 | break; |
12 | } |
13 | parent::__construct($msg,$code); |
14 | } |
15 | } |
このクラスは BaseException を継承しています。BaseException はデバッグ モードを実装しているため、ViewException にもこの機能があり、デバッグがオフになって例外がスローされた場合にのみジャンプします。エラーページに移動すると、例外が直接表示されないため、この処理の保守が容易になります。