"この記事では、コントローラーのインスタンス化を紹介し、ArrayAccess とインスタンスを返すマジック アクセスの直接実行の違いを分析します
"
上記の記事では、ルーティングについて説明しています。特別に詳細な説明もアプリケーションの初期化と解析から始まり、ルート スケジューリングがルート検出に戻るまでです。
ルート検出で得られる値は以下の通りで、最終的にルートスケジューリングで返される値となります。
使用するルーティングルールは Route::get('hello/:name', 'index/index/:name');
上の図からわかるように、重要なデータはdispatchcに保存され、その後制御が行われます装置について詳しく説明されています。
最初に説明するのは、ルート検出が完了した後に実行されるインスタンス化コントローラーの操作です。
まずはインスタンス化コントローラーの実行方法を見てみましょう!
最初にエントリ ファイルからコードを実行する必要があることは間違いありません。ここでは、コンテナを使用して App のインスタンスを返し、次に App クラスの run メソッドを呼び出します。
は、上記で解析されたルートも使用されます。
つまり、検出ルートが実行された後、ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考えるが実行されます。
ルーティング検出が完了すると、リターンはthinkroutedispatchModule Object
这个类,并且这个类赋值给了变量$dispatch
次に、このメソッドのこのコードを見てください。ここではミドルウェアが使用されています。ここで簡単に説明します。コード クロージャは依然として使用されています。クロージャの概念がよくわからない場合は、基本に戻る必要があります。
上の図の丸で囲った場所が$dispatch->run()
このコードは次に解析されます。 $dispatch->run()
这块代码,接下来就要对这块代码进行解析了。
在检测路由最终的返回值可以知道其实这个方法是在thinkroutedispatchModule
这个类中。
接着就需要对这个类中的run方法进行解析了,这个方法也就是ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える。
在这个方法中不管是获取路由参数还是检测路由、数据自动验证都不会执行(是按照咔咔上文给的路由地址为案例)。
所以根据上图代码就会执行到$data = $this->exec();
thinkroutedispatchModule
をこのクラスに追加します。 次に、このクラスの run メソッドを分析する必要があります。これは、ルーティングのスケジューリングを実行するためのものです。 ルーティング スケジューリングを実行します したがって、上記のコードに従って、コードは $data = $this->exec();
ここにあります。
は、上の図の原理に従って見ることができますDispatch
このクラスはArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考えるです。 Dispatch
这个类是ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える。
所以就会有俩种情况, 一种是ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える继承ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える,无需继承父类的抽象方法。
另一种是非抽象子类继承ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える,子类必须实现父类的所有抽象方法。
怎么去找谁继承了Dispatch
这个时候是不是有一个疑问就是怎么去找Dispatch的子类。
在这个图中可以看到本类Dispatch,但是还有一个dispatch这个目录。
根据ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える返回的数据可以轻而易举的就知道是thinkphp/library/think/route/dispatch/Module.php
thinkphp/library/think/route/dispatch/Module.php
このクラス。 🎜 は thinkphp/ library/think/route/dispatch/Module.php
Viewexec
メソッド。 thinkphp/library/think/route/dispatch/Module.php
查看exec
方法。
那么接下来的任务就是对这个方法进行深入的解读了。
先看第一行代码$this->app['hook']->listen('module_init');
,在这里使用了容器ArrayAccess用数组的形式访问对象,然后执行的ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える__get,当访问不存在的属性时会去执行make方法。
使用编辑器追踪这个app会到thinkphp/library/think/route/Dispatch.php
$this->app['hook']->listen('module_init');
、ここでコンテナ ArrayAccess は配列にアクセスします。オブジェクトをフォームに追加し、マジックメソッド __get を実行します。存在しない属性にアクセスすると、make メソッドが実行されます。 エディターを使用してこのアプリを追跡すると、thinkphp/library /think/route/Dispatch.php
このクラスのコンストラクターで、App インスタンスが app 属性に割り当てられていることがわかります。 🎜🎜🎜🎜アプリクラスのインスタンス化を探します🎜🎜🎜そして、Appクラスに到達すると、それがContainerクラスを継承していることがわかります。 🎜この知識ポイントについては、コンテナのコンテキストで何度も説明しましたが、存在しないプロパティにアクセスするには、戻ってコンテナの __get マジック メソッドを実行します。
そのため、このブロックのパラメータがフックに渡され、フックのインスタンスが返されることになります。このインスタンスがどのように返されるかについては、で説明されています。コンテナに関するセクションが詳しく説明されていますので、ぜひご覧ください。
その後、フックの listen メソッドが実行されて、タグの動作を監視します。
この時点で、このパラメータがモジュールに対して初期化されていることがわかりますが、この値は空です。
つまり、上の図では実行されないので、簡単なテストのためにこのパラメータにアプリケーションの初期化値を入れます。
このクラスはファサードクラスを最適化する実行フックです。
その後、コードが実行され、$results[$key] = $this->execTag($name, $tag, $params);
ここです。 $results[$key] = $this->execTag($name, $tag, $params);
这里来。
参数说明
接着通过正则对传过来的参数进行处理,最终返回moduleInit
然后通过$obj = Container::get($class);
返回behaviorLoadBehavior的实例
最终通过is_callable
这个函数进行验证,检测类里边的方法是否可以被调用,方法数组格式,这个方法后期咔咔单独写一篇文章作为对象来解析,这里只需要知道会返回false即可。
然后会把本类的$portal
这个值赋值给$method
,这个值就是run。
最后通过$result = $this->app->invoke($call, [$params]);
次に $obj = Container::get($class);
behaviorLoadBehavior のインスタンスを返します
is_callable
この関数は、クラス内のメソッドを呼び出すことができるかどうかを検証します。このメソッドの後に、Kaka は解析するオブジェクトとして別の記事を作成します。ここでは false が返されることだけを知っておく必要があります。 🎜🎜次に、$portal
この値は$method
、この値は走る。 🎜🎜最後に$result = $this->app ->invoke($call, [$params]);
このコード行、このコード行の一番下の実行は、リフレクション メカニズムを通じて実装されます。 🎜🎜最後のコードは NULL を返します。 🎜🎜🎜ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える🎜🎜次のステップは、コントローラーをインスタンス化することです。呼び出しメソッドは $this->app->controller()
$this->app->controller()
这里需要注意的是list这个函数,这个函数的后边会返回一个数组,然后list中的俩个变量会分别为索引0和1。
判断也会去执行第一个,同样会执行到容器类的make方法,这个方法会直接返回appindexcontrollerIndex
この 2 つの場所で曖昧な部分があると推測されます。Kaka はこれら 2 つをまとめて分析します。
まず ArrayAccess の使用方法について話しましょう
これは以前に書いたテストメソッドです
そして、それを使用するためにコントローラーに来たら、最初にインスタンス化します。以前に実装されたケースは次のとおりです。 🎜🎜しかし、今回実装する必要があるケースは、下の図に実装されているものではありません。 🎜次に、下図に示すメソッドを使用して、配列を使用してオブジェクトのプロパティに直接アクセスします。
上の図では、属性 title が kaka に設定されていることがわかります。この場合、配列の形式で直接取得されます。
戻り結果が kaka であることを確認してください。これは、オブジェクトのプロパティが配列形式で直接アクセスされていることを意味します。
概要
最初のケースの実装プロセスでは、オブジェクトを使用してオブジェクトのプロパティに直接アクセスするステップが無視されました。配列の形式で。
目に見えるものは直接取得できるので、この考え方をフレームワークに落とし込んで見てみましょう。
フレームワーク実践事例
前回の記事で解析したルートには以下のコードが存在します。簡単に解析してみましょう。
まず、印刷時のこのアプリの値を見てみましょう: thinkApp オブジェクト
オブジェクト。 thinkApp Object
对象。
当thinkApp Object
这个对象去访问request
时,因为app属性就没有这个request
次に、Kaka が簡単なテストを行ってそれを確認します。
この位置にランダムな値を出力します。
次に、コンテナクラスのArrayAccessのoffsetGetメソッドに移動し、渡された値を出力します。
印刷された結果を見ると、非常に明確になります。
これも前回を踏まえた詳しい説明です 次にコンテナ内の内容については __get メソッドで説明します。詳細を参照して、__get メソッドがどのような状況で実行されるかを確認します。
__getメソッドの詳しい説明
この場合については、下の画像を参照してください$this->hook
。
同じ理由で、最初にこれをデバッグしましょう$this
の値は何ですか。 $this
是什么值。
打印这个值都没什么必要,因为就是在本类中。
在类中属性的访问应该都会,就是直接使用$this->
即可。
所以说当系统访问$this->hook
クラスの属性$this-> で十分です。
次に、makeメソッドを実行してクラスのインスタンスを作成します。
🎜🎜🎜 クラスのインスタンスを作成する 🎜🎜🎜🎜 概要 🎜🎜そこで、ArrayAccess と __get マジック メソッドを使用し、最終的に実行された make メソッドはクラスのインスタンスを返します。
this->config に遭遇すると、実行されるのはコンテナの __get メソッドです。
app['request']に遭遇すると、ArrayAccessが実行され、次にoffsetGetが実行されます
offsetGet
以上がArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考えるの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。