"この記事では、コントローラーの最終実行プロセスと使用される 2 つの高度な属性について簡単に説明します。1 つは fastcgi_finish_request メソッドの賢い使用法で、もう 1 つは特性機能です。概念はある程度理解しています。一緒に解析してみましょう
ここにあるデータが最終的にどこに返されるかについて少し混乱していますか?
したがって、 run メソッドが実行されると、対応する結果がここに返されます。
が App クラスのインスタンスを返すことは皆さんご存知のはずです。Container::get('app')
次に、App クラスを通じて run メソッドを実行すると、前に述べたすべてが得られます。
下の写真は、腰の真ん中からKakaが作成したマインドマップです。前の部分は存在せず、後ろの知識ポイントはすべてこのマインドマップに書き込まれます。
runメソッド実行後、Container::get('app')->run()->send()
send メソッドが App クラスで実行されると考える人はどれだけいるでしょうか。 Container::get('app')->run()->send()
send这个方法,有多少人会认为在App类里边执行send方法。
其实不是的,回想一下之前执行控制器方法然后返回的响应结果是什么?
如果你不是很粗略的看都会记得是Response的一个对象实例。
所以说send方法会去response类里边去执行。
先不看其它的,先看这行代码$this->app['hook']
,现在知道是执行的那里吗?
这种形式就是通过访问数组形式去访问对象的属性,也就是之前解析的ArrayAccess这个类。当访问的属性不存在时会去执行offsetGet,然后执行魔术方法__get,最终通过make方法返回实例,这一切的操作都是在容器中。
对这行代码具体是监听的什么就不去做解析了。
接着需要看处理ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能的这行代码$data = $this->getContent();
$this->app['hook']
、どこにあるかわかりますか処刑された? 🎜🎜このフォームは、先ほど解析したArrayAccessクラスである配列にアクセスすることでオブジェクトのプロパティにアクセスするフォームです。アクセスされた属性が存在しない場合は、offsetGet が実行され、次にマジック メソッド __get が実行され、最後に make メソッドを通じてインスタンスが返されます。これらの操作はすべてコンテナ内で実行されます。 🎜🎜このコード行が正確に何を監視しているのかは分析しません。 🎜🎜次に、出力データを処理するコード行を確認する必要があります$ data = $this->getContent();
🎜🎜 このメソッドが行うことは、渡されたデータをこのクラスの content 属性に割り当てることです。 🎜実は、この出力データを取得する方法ですが、最初の丸で囲った部分を見てください。
データはまったく処理されておらず、ただ返されていることがわかります。したがって、このフレームワークには、読んでみなければわかりません。そうでないと、よく使うものについて混乱するでしょう。 . ツールは何も知りません。
次のステップは、トレース デバッグ インジェクションです。これは、構成ファイルを通じて構成され、デバッグ クラスを呼び出すことによって実装されますが、ここでは詳しく説明しません。
その後、キャッシングの判定があります。キャッシングについては、次の記事で別途説明するので、パスします。
次のステップは、応答ヘッダーを設定し、HTTP ヘッダーが送信されたかどうかを検出することです。これは非常に重要ですが、あまり公開されない知識ポイントでもあります。
最後のステップ、来て、来て、エコーを伴ってメソッドを実行します$this->sendData($data);
法律は義母になりましたついに終着点に到着したように感じ、エコーは数十日間の悲しみを出力しました!
このエコーカカに到達するために、私たちは9981の困難を乗り越えてきました!戦いはまだ終わっていない、仲間たちはまだ頑張らなければなりません!
そこで、ここではフレームワークの実行、次にアプリケーションの初期化、ルート検出、コントローラーのインスタンス化、そして応答インスタンスに戻り、エントリーファイルを介して send メソッドを実行します。
最後にデータを端末に出力します。これがエコーです。
ここでの戦いは終わりましたが、以下に非常に重要な知識ポイントがまだあり、カカはそれを説明するためにもう一度言及します。
前のセクションで渡された Container::get('app')->run()->send();
レスポンスクラスでsendメソッドが実行されデータが出力されます。 Container::get('app')->run()->send();
在response类中执行了send方法,输出了数据。
但是在ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能之后还执行了一个方法fastcgi_finish_request();
fastcgi_finish_request ();
に与えられたコメントは、ページの応答を改善するためのものです。謎を詳しく見てみましょう。 この一節を PHP 公式 Web サイトで見ました スクリプトは fastcgi_finish_request() の後も FPM プロセスを占有するため、長時間実行されるタスクに過度に使用すると、pm.max_children までのすべての FPM スレッドが占有される可能性があります。 Web サーバーでゲートウェイ エラーが発生しました。fastcgi_finish_request() の後、スクリプトは引き続き FPM プロセスを占有します。 そのため、長時間実行されるタスクでこれを過度に使用すると、すべての FPM スレッドが pm.max_children まで拘束される可能性があります。 これにより、Web サーバーでゲートウェイ エラーが発生します。
したがって、この方法を完全に理解せずに、自分のプロジェクトでこの方法を使用しないでください。 次に、Kaka はこのメソッドの使用法を示すためにケースを使用します。これは単なるデモンストレーションです。プロジェクトで使用する必要がある場合は、ドキュメントをよく読んで問題点に注意してください。ケースデモンストレーション
🎜会社はユーザーに通知を送信する必要があるビジネスを行っていますが、送信時間が長すぎるため、非常に時間がかかります。場合によっては数十秒かかる場合があり、さらに深刻な場合はブラウザの接続に時間がかかることがあります。外。
1 つの問題はユーザー エクスペリエンスであり、ユーザー エクスペリエンスは確かに良くありません。
上記の 2 つの問題を解決するために、今日お話しするのは fastcgi_finish_request
が便利です。 fastcgi_finish_request
就派上了用场。
理解
对这个函数的理解其实就是发送响应给浏览器,用户等待时间大大缩短,但是PHP进程还是在运行的。
这样就达到了来个目的,就类似于我们经常说的异步执行。
直观的来说就是发送邮件有可能需要10秒,但是用户是没有感知的,用户点击发送邮件之后直接就返回发送成功,浏览器响应结束,用户做其它事情,后台进程继续执行发送邮件的任务。
案例
具体代码
<span style="display: block; background: url(https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #282c34; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"></span><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; padding-top: 15px; background: #282c34; border-radius: 5px;"><span class="hljs-meta" style="color: #61aeee; line-height: 26px;"><?php</span><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 设置超时时间,变成不限制<br/> *<br/> */</span><br/>set_time_limit(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span>);<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 本函数模拟非常耗时的任务,执行完毕需要5秒的时间<br/> */</span><br/><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">function</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">writeFile</span><span class="hljs-params" style="line-height: 26px;">()</span><br/></span>{<br/> $path = <span class="hljs-string" style="color: #98c379; line-height: 26px;">'D:/phpstudy_pro/WWW/kaka.txt'</span>;<br/> file_put_contents($path,<span class="hljs-string" style="color: #98c379; line-height: 26px;">'程序运行开始'</span> . PHP_EOL,FILE_APPEND);<br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span>($i =<span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span>;$i < <span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>;$i++) {<br/> file_put_contents($path,time() . PHP_EOL,FILE_APPEND);<br/> sleep(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>);<br/> }<br/><br/> file_put_contents($path,<span class="hljs-string" style="color: #98c379; line-height: 26px;">'程序运行结束'</span> . PHP_EOL,FILE_APPEND);<br/><br/>}<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 输出文字标记,任务开始<br/> */</span><br/><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">echo</span>(<span class="hljs-string" style="color: #98c379; line-height: 26px;">'任务开始'</span>);<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 后台执行非常耗时的任务<br/> */</span><br/>register_shutdown_function(writeFile);<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 立即发送请求<br/> */</span><br/>fastcgi_finish_request();<br/><br/><br/><br/></code>
以上测试全部使用linux系统进行测试哈,否则你看不到直观的效果。
经过上面的演示,响应非常快,浏览器响应结束后,后台程序依然进行执行每秒执行一个时间戳。
以上就是对fastcgi_finish_request
fastcgi_finish_request
メソッドは簡単な紹介、もし興味があれば、ちょっとした秘密をより深く理解するのに役立つ簡単な試してみることができます。 🎜それはよくスーパークラスと呼ばれます。 trait
上の図から、メソッドが Test スーパー クラス ファイルを返すことがわかりますが、このコントローラーは、この記事の冒頭で説明したスーパー クラスであるコントローラー コントローラーにも基づいています。多重継承の関数を実装するだけです。
しかし、ここで問題が発生します。以下のエラーメッセージを参照してください。
上の図のエラー メッセージは、コントローラーで 2 つのスーパー クラスを使用することによって発生します。これは、下の図でどのように使用されているかです。
それでは、このエラー メッセージを解決する方法を説明します。次に、このクリックのリズムに従います。
エラーメッセージの解決
前の問題を解決する前に、まずこの問題の原因を理解する必要があります。
このエラーの理由は、参照されている 2 つの特性に同じ名前の hello 関数があり、競合が発生しているためです。
しかし、メソッド名を手動で変更するのは依然として非常に便利なので、この状況は日常の開発では回避できますが、ここで Kaka がこの問題の解決方法を教えます。
1 つ目は、あるトレイトで hello メソッドを使用して、別のトレイトの同じ名前のメソッドを上書きすることです。2 つのメソッドの内容は一貫しているため、ここで上書きする代わりに、直接選択します。競合が起こらないよう、エイリアスとして as を付けます。 as キーワードには、メソッドのアクセス制御を変更するという別の用途もあります。
上の図を変更した後、再度アクセスして、返された結果を確認してください。
次に、この時点で一部のパートナーから質問があるでしょう。つまり、ケースの出力結果は常に Test クラスのメソッドであり、Test1 クラスのメソッドは出力されていません。
それでは訪問方法を説明します!見てみましょう。
上の図から、アクセス方法がエイリアス制御アクセスに変更されたことがわかります。次に、アクセス結果を見てみましょう。
上の図からわかるように、戻り結果はスーパークラス Test1 の戻り結果です。
そのため、as の使用に関しては、詳細に注意して使用方法を検索する必要がある場合があります。
コントローラーのソースコード分析については、Kaka がソースコードを通じてコントローラーがどのようにインスタンス化されるかを分析します。
ArrayAccess とマジック メソッドの呼び出し関係についても再度説明しました。この問題を考えるには、独自の考え方が必要です。
コントローラーなどにアクセスした後のデータの応答方法です。
ソースコードでの fastcgi_finish_request メソッドの賢い使い方についても学びましたが、この関数を使用する場合は、Kaka について述べた 2 つの点に注意する必要があります。
最後に、スーパークラスの簡単なケースの説明があります。
「学習への粘り強さ、ブログへの粘り強さ、そして共有への粘り強さは、カカがキャリア以来貫いてきた信念です。巨大なインターネット上のカカの記事が少しでもお役に立てれば幸いです。」カカ、次号でお会いしましょう
”
以上がThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。