PHP フレームワークをステップバイステップで作成する (10)

WBOY
リリース: 2016-06-21 08:50:30
オリジナル
866 人が閲覧しました

実際にはフレームワークの単なる棚です。今日から、これらをコントローラー、モデル、ビューから分離していきます。私が紹介します。

PS: ルーティングなど、これまでの内容の多くについては詳しく説明しませんでしたが、実際のフレームワークのルーティングは GET を通じて指定されるものではなく、通常のものであり、複数のサーバーと互換性がある必要があります。複数の方法。

すべてのリクエストはコントローラーを経由する必要があることがわかっているので、最初にコントローラーについて話しましょう。

以前にコントローラーの概念について説明しましたが、このコントローラーは機能的には単なるコントローラーであり、フレームワークは実際に一般的に使用されるいくつかの機能を実装できるわけではないため、まだ弱すぎます。関数を作成し、ユーザー定義のコントローラーがそれを継承するため、ユーザーが記述するコードが少なくなります。

以前のコントローラーは次のとおりです:

1

1

2 class IndexController {

3 public function index() {

4 echo 'Hello world';
<テーブル>

2

5 }

6 }
クラス IndexController {

<テーブル> 3

パブリック関数 Index() {

1

<テーブル>

2 class IndexController extends Controller {
4

3 public function index() {
<🎜> echo 'Hello world';<🎜><🎜> <🎜> <🎜> <テーブル> <🎜><🎜>5<🎜><🎜> <🎜><🎜> }<🎜><🎜> <🎜> <🎜> <テーブル> <🎜><🎜>6<🎜><🎜> <🎜><🎜>}<🎜><🎜> <🎜> <🎜> <🎜> <🎜> <🎜><🎜>フレームワークがコントローラーのいくつかの基本機能を実装していると仮定すると、このクラスは Controller.php と呼ばれ、コードは次のようになります。 <🎜><🎜><🎜> <🎜> <🎜> <🎜> <テーブル> <🎜><🎜>1<🎜><🎜> <🎜><🎜><🎜> <🎜> <🎜> <テーブル> <🎜><🎜>2<🎜><🎜> <🎜><🎜>クラス IndexController はコントローラ {<🎜><🎜> を拡張します <🎜> <🎜> <テーブル> <🎜><🎜>3<🎜><🎜> <🎜><🎜> パブリック関数 Index() {<🎜><🎜>

4 echo 'Hello world';

5 }

6 }

これを行う利点は何ですか? Controller が Base を継承しているため、IndexController も Base の機能を備えているため、ユーザーは多くのキャプチャ コードを記述する必要がありません。

もちろん、これにも欠点があり、IndexController をテストするときはさらに面倒です。

今日はまず、コントローラーの 2 つの基本機能、ジャンプと前進について説明します。

1 つ目はジャンプです。たとえば、ユーザーがログインするときに、処理が完了した後にログイン ボタンをクリックして、バックグラウンド処理ページに移動する必要があります。ジャンプを実装するにはどうすればよいですか?

いくつかの方法があります:

最初のもの: <script>location.href = "XXXX";</script>JS でジャンプを実現します。

2 番目のタイプ: header("Location:url"); 具体的な使用法については、PHP マニュアルを参照してください。

3 番目の方法: HTML メタで更新を設定します。

ヘッダーを呼び出した時点で、前のページに出力があるとジャンプが無効になるため、metaのリフレッシュと併用する必要があります。 もちろん、JSを直接使用して実装することもできます。 、しかし、私はこの方法があまり好きではありません。なぜなら、以前にこの方法を使用してジャンプを実装したときに問題があったからです。

ジャンプ関数の名前を _redirect として定義します。なぜその前に _ を追加するのでしょうか? これは私の習慣でもあり、関数がパブリックでない限り、_ を使用します。接頭辞。なぜこの関数を public に設定しないのかと疑問に思われるかもしれません。ユーザーが作成したコントローラーはそれを継承するだけで、直接呼び出すことはないため、私はそれを protected に設定しました。

1

保護された関数 _redirect(Array $arr) {

1 protected function _redirect(Array $arr) {
テーブル>

2  

2

3  
テーブル>

4 }
3 テーブル> 4 } テーブル>

当面は、ジャンプ パラメータが配列を介して渡されると仮定すると、渡されたパラメータがそうでない場合は、型ヒント (Array $arr) を使用してそれを行うことができます。配列の場合、エラーが直接報告されます。

これを使用する方法は次のようになります:

1 $this->_redirect(array(
1

2         'action' => 'test',

$this->_redirect(array(

3         'controller' => 'Test',
テーブル>

4         'param1' => '1'

2

5 ));

'アクション' => 'テスト'、 テーブル>

3

'コントローラー' => 'テスト'、

01 protected function _redirect(Array $arr) {
テーブル>

02         $controller= empty($_GET['c']) ? C('defaultController') : trim($_GET['c']); //设置了默认的控制器
4

03         $action= empty($_GET['a']) ? C('defaultAction') : trim($_GET['a']); //设置了默认的Action

'param1' => '1'

04         array_key_exists('controller',$arr)  $arr['controller'] = $controller;
テーブル> 5 )); テーブル> これは、テスト コントローラーのテスト アクションにジャンプすることを意味し、値 1 を持つ param1 という名前のパラメーターも渡します。 01 保護された関数 _redirect(Array $arr) { テーブル> 02 $controller= empty($_GET['c']) ? C('defaultController') : trim($_GET['c']) //デフォルトのコントローラーが設定されています テーブル> 03 $action= empty($_GET['a']) ? C('defaultAction') : trim($_GET['a']); // デフォルトのアクション テーブル> 04 array_key_exists('controller',$arr) $arr['controller'] = $controller; テーブル>

05         array_key_exists('action',$arr)  $arr['action'] = $action;

06         $str = '/?';

07         foreach($arr as $key => $val) {

08             if(!is_int($key)) {

09                 $str .= ($key . '=' . $val . '&');

10             }

11         }

12         $str = substr($str,0,strlen($str) - 1);

13         Response::redirect($str);

14     }

これは先ほど手書きしたジャンプコードです。実際には渡された配列を連結して文字列を形成します。Route.php がまだ処理されていないため、さらに処理します。 localhost/demo2/index.php?controller=a のような URL の場合、ジャンプ時にエラーが発生します。現在、localhost/index.php?controller=a のような URL と、$controller および $action の取得のみがサポートされています。これらは後で実際にルーティングを実装するときに説明する必要がありますが、私自身はこのようなコードは気持ち悪いと感じています。

この関数が URL に結合されると、Response のリダイレクト メソッドが直接呼び出されることに気づいたかもしれません。これはなぜでしょうか。

最初に: 実際のアプリケーションでは、コントローラー内で $this->_redirect を直接呼び出すことがニーズを満たすことができない可能性があります。現時点では、jump To などの Response::redirect を直接呼び出す必要があります。 Baidu のホームページにアクセスすると、Response::redirect("http://www.baidu.com");

のみを呼び出すことができます。

2 番目: 論理的には、ジャンプはサーバーからクライアントへの応答であるため、Response に記述する必要があります。詳細については、Java を参照してください。

次に、Response.php のような新しいファイルを作成する必要があります:

01

01

02 class Response extends Base {

03 public static function redirect($url) {

04 if(is_string($url)) {
<テーブル>

02

05 if(!headers_sent()) {

06 header("Location:" . $url);
クラス Response extends Base {

07 exit();

<テーブル>

08 } else {
03<🎜><🎜> <🎜><🎜> public static function redirect($url) {<🎜><🎜> <🎜> <🎜> <テーブル> <🎜><🎜>04<🎜><🎜> <🎜><🎜> if(is_string($url)) {<🎜><🎜> <🎜> <🎜> <テーブル> <🎜><🎜>05<🎜><🎜> <🎜><🎜> if(!headers_sent()) {<🎜><🎜> <🎜> <🎜> <テーブル> <🎜><🎜>06<🎜><🎜> <🎜><🎜> header("場所:" . $url);<🎜><🎜> <🎜> <🎜> <テーブル> <🎜><🎜>07<🎜><🎜> <🎜><🎜> exit();<🎜><🎜> <🎜> <🎜> <テーブル> <🎜><🎜>08<🎜><🎜> <🎜><🎜> else {<🎜><🎜>

09 $str = '';

10                 exit($str);

11             }

12         } else {

13             //错误处理

14         }

15     }

16 }

実際には、出力があるかどうかを判断するため、出力がある場合は header("Location") を使用してジャンプします。メタのリフレッシュでジャンプ。

注: 実際には、このジャンプではさらに多くの機能を開発できますが、簡単に説明するだけなので、これ以上の内容は書きません。興味のある方は Toper にアクセスして読んでください。 。

このようにして、比較的単純なジャンプが完了しましたが、転送をどのように実装するか?

転送とは、実際には特定のコントローラーのアクションを再度呼び出すことであると単純に理解できます。

このようにして、比較的簡単に転送を実装できます:

01 protected function _forward(Array $arr) {
01 保護された関数 _forward(Array $arr) { テーブル>

02         $controller= empty($_GET['c']) ? C('defaultController') : trim($_GET['c']); //设置了默认的控制器

03         $action= empty($_GET['a']) ? C('defaultAction') : trim($_GET['a']); //设置了默认的Action

04         if(array_key_exists('controller',$arr)) {

05             $controller = $arr['controller'];

06         }

07         if(array_key_exists('action',$arr)) {

08             $action = $arr['action'];

09         }

10         $controller .= 'Controller';

11         if($controller === get_class()) {

12             if(method_exists($this,$action)) {

13                 $this->$action();

14             } else {

15                 //时间有限,不写逻辑了

16             }

17         } else {

18             if(class_exists($controller)) {

19                 $class = new $controller();

20                 if(method_exists($class,$action)) {

21                     $class->$action();

22                 } else {

23                     //时间有限,不写了

24                 }

25             } else {

26                 //时间有限,不写了

27             }

28         }

29     }

実際、ロジックは、呼び出されるアクションがこのコントローラーに属するかどうかを判断することです。このコントローラーの場合は、$this->$action() を直接呼び出すだけです。それ以外の場合は、インスタンスを作成する必要があります。このコントロール、つまり $class = new $controller() を呼び出して、このアクションを呼び出します。

書くのに30分かかると思っていましたが、時間が予算を超えたので、文法的な間違いがあるかどうかはわかりませんが、結局1時間かかりました。とにかく見てください アイデアを見るだけでOKです。



関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート