ホームページ  >  記事  >  PHPフレームワーク  >  ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

咔咔
咔咔オリジナル
2020-12-29 11:31:491591ブラウズ
#"この記事では、入門書としてコントローラーをインスタンス化し、ArrayAccess と、インスタンスを返すマジック アクセスを直接実行する場合の違いを分析します。

"

前書き

#ルーティングについては、アプリケーションの初期化と解析から始まり、ルート スケジューリングがルート検出に戻るまで、上で詳しく説明しました。

ルート検出で得られる値は以下の通りで、最終的にルートスケジューリングで返される値となります。

使用されるルーティング ルールは

Route::get('hello/:name', 'index/index/:name');

# です。 ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

#印刷場所

上図からも分かるように、dispatchcには重要なデータが格納されており、次にコントローラについて詳しく説明します。

最初に、配線検出完了後のインスタンス化コントローラーの動作について説明します。

1. インスタンス化コントローラー

#まずはインスタンス化コントローラーの実行方法を見てみましょう。

最初にエントリ ファイルからコードを実行する必要があることは間違いありません。ここでは、コンテナを使用して App のインスタンスを返し、次に App クラスの run メソッドを呼び出します。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

下に降りると実行アプリケーションにたどり着きます。上記で解析されたルートです。

したがって、検出ルートが実行された後、インスタンス化されたコントローラーが実行されます。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

ルート検出の実行後に返されるのは、think\route\dispatch\Module です。オブジェクト このクラス、およびこのクラスは変数 $dispatch に割り当てられます

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

上の図で丸で囲まれた場所はコード $dispatch->run() で、次のステップは分析です。このコード部分。

ルートの最終的な戻り値を検出すると、このメソッドが実際には think\route\dispatch\Module クラスにあることがわかります。

次に、ルーティング スケジューリングを実行する、このクラスの run メソッドを分析する必要があります。

この方法では、ルーティングパラメータの取得、ルーティングの検出、自動データ検証は実行されません(上記のルーティングアドレスは例として使用されます)。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

したがって、上記のコードによると、コードは$data = $まで実行されます。 this-> exec();ここ。

このメソッドをたどると、下図のような抽象クラスが存在することにたどり着きますが、ここで知っておく必要があるのは抽象クラスです。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

抽象クラスの説明

  • 抽象クラスはインスタンス化できません
  • #抽象メソッドを持つクラスは抽象クラスである必要があり、クラスは抽象で修飾されている必要があります
  • #Abstractメソッド 関数本体は存在できません。つまり、抽象関数 fun();
  • 抽象クラス内の非抽象メソッドはサブクラスから呼び出すことができます
  • 非抽象 サブクラスは抽象クラスを継承し、サブクラスは親クラスのすべての抽象メソッドを実装する必要があります
  • 抽象サブクラスは抽象クラスを継承し、その必要はありません親クラスの抽象メソッドを継承する
  • 上図の原理によれば、
Dispatch

このクラスは抽象クラスであることがわかります。 つまり、2 つの状況が考えられます。1 つは、抽象クラスが親クラスの抽象メソッドを継承せずに、抽象クラスを継承する場合です。

もう 1 つは、非抽象サブクラスは抽象クラスを継承し、サブクラスは親クラスのすべての抽象メソッドを実装する必要があることです。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

Dispatchを継承した人を確認する方法

次の場所にありますか?今回は? 1 つの質問は、Dispatch のサブクラスを見つける方法です。

この図にはこのタイプのディスパッチが表示されていますが、ディスパッチ ディレクトリもあります。

ルート検出によって返されたデータによると、それがクラス thinkphp/library/think/route/dispatch/Module.php であることが簡単にわかります。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

thinkphp/library/think/route/dispatch/Module.php## にアクセスしてください#Viewexecメソッド。

それでは、次のタスクは、このメソッドの詳細な解釈を行うことです。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

最初にコードの最初の行を確認してください$this->app['hook ' ]->listen('module_init');、ここでは、コンテナ ArrayAccess を使用して配列形式のオブジェクトにアクセスし、マジック メソッド __get を実行します。存在しない属性にアクセスする場合、 makeメソッドが実行されます。

エディタを使用してこのアプリを追跡すると、thinkphp/library/think/route/Dispatch.phpこのクラスに移動します。このクラスのコンストラクターでは、 app の属性は App インスタンスが割り当てられます。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

次に、App クラスに到達すると、それが次のとおりであることがわかります。 Container クラスから継承されます。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

このナレッジ ポイントについては、コンテナのコンテキストで複数回説明しました。存在しないプロパティにアクセスするには、戻って、クラスの __get マジック メソッドを実行します。容器。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

したがって、このブロックのパラメータはフックして返されるフック インスタンス、このインスタンスがどのように返されるかについては、コンテナーのセクションで詳しく説明されています。ご覧ください。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

#フックのインスタンスを返します

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

ラベル動作の監視

したがって、上の図では実行されないため、簡単なテストのためにこのパラメータにアプリケーションの初期化値を入力します。

このクラスは、ファサード クラスの最適化操作である実行フックです。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

その後、コードは$results[$key] = $まで実行されます。 this ->execTag($name, $tag, $params);ここ。

パラメータの説明

  • $name = string(22) "behavior\LoadBehavior"
  • $tag = module_init

次に、渡されたパラメータが正規表現によって処理され、最後に moduleInit が返されます。

そして、$obj = Container::get($class);# によって処理されます。 ## Behavior\LoadBehavior のインスタンスを返します

最後に、クラス内のメソッドを呼び出せるかどうかを確認するための is_callable 関数を渡しました。メソッドの配列形式です。このメソッドは、解析するオブジェクトとして別の記事を書くために使用されます。ここでは、ここでのみ説明します。 false が返されることを知っておく必要があります。

次に、このクラスの $portal 値が $method に割り当てられ、この値が実行されます。

最後に渡します$result = $this->app->invoke($call, [$params]);このコード行、このコード行の最後の実行これはメカニズムによって実装されたリフレクションを通じて行われます。

最後のコードは NULL を返します。

コントローラーのインスタンス化

次のステップはコントローラーをインスタンス化することです。呼び出しメソッドは #$this->app->controller()

ここで注意する必要があるのは list 関数です。この関数は配列を返し、リスト内の 2 つの変数のインデックスはそれぞれ 0 と 1 になります。

最初の判定も実行され、コンテナクラスのmakeメソッドも実行され、app\index\controller\Indexのインスタンスが直接返されます。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

2. との違いについてArrayAccess とインスタンスを返すためのマジック アクセスの直接実行

ArrayAccess とマジック メソッド __get の使用法を学習した友人もいます。

この 2 か所には、あいまいな領域にあるものがあると推定されます。Kaka はこれら 2 つをまとめて一度分析します。

最初に ArrayAccess の使用方法について話しましょう

このケースは、主に ArrayAccess クラスを実装するために以前にデモされました。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

それから、それを使用するためにコントローラーを使用するときは、最初にそれをインスタンス化し、以前の場合は次のようになります。

ただし、今回実装する必要があるケースは、下図に実装されているものではありません。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

次に、下図に示すメソッドを使用して、配列を使用してオブジェクトのプロパティに直接アクセスします。

上の図では、属性 title が kaka に設定されていることがわかりますが、この場合、配列形式で直接取得できます。

戻り結果が kaka であることを確認してください。これは、オブジェクトのプロパティが配列形式で直接アクセスされることを意味します。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

概要

最初のケースの実装プロセスでは、オブジェクトを使用して目的を達成するというステップが無視されました。配列を直接使用する フォームはオブジェクトのプロパティに直接アクセスします。

目に見えるものは直接取得できるので、この考え方をフレームワークに落とし込んで見てみましょう。

フレームワーク実践事例

前回の記事で解析したルーティングには以下のコードが存在するので、簡単に分析してみましょう。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

まずこのアプリの値を見て、think\ として出力してみましょう。アプリオブジェクトオブジェクト。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

think\App Object がアプリ属性にこれがないため、このオブジェクトは request にアクセスしますrequest とすると、アプリクラスはコンテナクラスを継承しているため、コンテナクラスに移動して以下のメソッドを実行します。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

次に、__get メソッドが実行され、make メソッドが実行されて対応するインスタンスが返されます。 。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

現時点でまだご質問がある場合は、なぜ次のようなメッセージが表示されるだけなのでしょうか。実行されますか? 実行されます!

次に、カカが全員に簡単なテストをしてもらいます。そうすればわかります。

この位置にランダムな値を出力します。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

次に、コンテナ クラスの ArrayAccess の offsetGet メソッドに移動し、渡された値を出力します。

印刷結果を見ると、非常に鮮明です。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

ArrayAccess の使い方はここまでです。前回を踏まえてこちらも詳しく説明します。次に、__get がどのような状況で実行されるのか、コンテナ内の __get メソッドについて詳しく説明します。

__getメソッドの使い方の詳しい説明

このケースについては、下の図の $this->hook を参照してください。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

同じ理由で、最初に $this の値をデバッグしましょう。

この値はこのクラスにあるため、出力する必要はありません。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

クラス内の属性にアクセスできるはずです。$this-> を使用するだけです。 # ## それでおしまい。

したがって、システムが $this->hook にアクセスすると、App クラスにはフック属性がないため、コンテナ クラスのマジック メソッドが実行されます。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

次に、make メソッドを実行してクラスのインスタンスを作成します。

ArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考える

概要

したがって、ArrayAccess を使用し、最終的に __get マジック メソッドが実行され、make メソッドがクラスのインスタンスを返します。

これが発生した場合、config は実行されるコンテナーの __get メソッドです。

app['request'] に遭遇したら、ArrayAccess を実行してから offsetGet を実行します

  • #__get はクラスの属性を取得するもので、クラスの属性が存在しない場合に実行されます。インスタンス化されたクラスに配列形式でアクセスします。クラスが存在しない場合は、
    offsetGet
  • メソッドが実行されます。
  • 推奨チュートリアル: 「thinkphp

以上がArrayAccess とダイレクト マジック アクセス リターン インスタンスの違いについて ThinkPHP で考えるの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。