ホームページ >PHPフレームワーク >ThinkPHP >ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能

咔咔
咔咔オリジナル
2020-12-04 13:14:30191ブラウズ
"

この記事では、コントローラーの最終実行プロセスと使用される 2 つの高度な属性について簡単に説明します。1 つは fastcgi_finish_request メソッドの賢い使用法で、もう 1 つは特性機能です。概念はある程度理解しています。一緒に解析してみましょう

コントローラーでメソッドを実行した後、応答データが の run メソッドに送信されます。 Appクラス、ここまでで実行は完了です。

ここにあるデータが最終的にどこに返されるかについて少し混乱していますか?

アプリケーションを実行しますThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
前に書いたフレームワークの実行処理、ルーティング、コントローラーのインスタンス化はすべてここから始まります。

したがって、 run メソッドが実行されると、対応する結果がここに返されます。

アプリケーションを実行して応答します ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
コードのこの部分
が App クラスのインスタンスを返すことは皆さんご存知のはずです。

Container::get('app')次に、App クラスを通じて run メソッドを実行すると、前に述べたすべてが得られます。

下の写真は、腰の真ん中からKakaが作成したマインドマップです。前の部分は存在せず、後ろの知識ポイントはすべてこのマインドマップに書き込まれます。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
実行処理

runメソッド実行後、Container::get('app')->run()->send()send メソッドが App クラスで実行されると考える人はどれだけいるでしょうか。 Container::get('app')->run()->send()send这个方法,有多少人会认为在App类里边执行send方法。

其实不是的,回想一下之前执行控制器方法然后返回的响应结果是什么?

如果你不是很粗略的看都会记得是Response的一个对象实例。

所以说send方法会去response类里边去执行。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能

先不看其它的,先看这行代码$this->app['hook'],现在知道是执行的那里吗?

这种形式就是通过访问数组形式去访问对象的属性,也就是之前解析的ArrayAccess这个类。当访问的属性不存在时会去执行offsetGet,然后执行魔术方法__get,最终通过make方法返回实例,这一切的操作都是在容器中。

对这行代码具体是监听的什么就不去做解析了。

接着需要看处理ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能的这行代码$data = $this->getContent();

実際にはいいえ、以前にコントローラー メソッドを実行した後に返された応答結果を思い出してください。

あまり大まかに見なければ、Response のオブジェクトのインスタンスであることを覚えているでしょう。 🎜🎜つまり、sendメソッドはレスポンスクラスで実行されます。 🎜🎜ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能🎜クライアントにデータを送信します🎜🎜🎜他には何も見ずに、最初にこのコード行を見てみましょう$this->app['hook']、どこにあるかわかりますか処刑された? 🎜🎜このフォームは、先ほど解析したArrayAccessクラスである配列にアクセスすることでオブジェクトのプロパティにアクセスするフォームです。アクセスされた属性が存在しない場合は、offsetGet が実行され、次にマジック メソッド __get が実行され、最後に make メソッドを通じてインスタンスが返されます。これらの操作はすべてコンテナ内で実行されます。 🎜🎜このコード行が正確に何を監視しているのかは分析しません。 🎜🎜次に、出力データを処理するコード行を確認する必要があります$ data = $this->getContent();🎜🎜 このメソッドが行うことは、渡されたデータをこのクラスの content 属性に割り当てることです。 🎜
ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
出力データを取得する

実は、この出力データを取得する方法ですが、最初の丸で囲った部分を見てください。

データはまったく処理されておらず、ただ返されていることがわかります。したがって、このフレームワークには、読んでみなければわかりません。そうでないと、よく使うものについて混乱するでしょう。 . ツールは何も知りません。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
データの処理

次のステップは、トレース デバッグ インジェクションです。これは、構成ファイルを通じて構成され、デバッグ クラスを呼び出すことによって実装されますが、ここでは詳しく説明しません。

その後、キャッシングの判定があります。キャッシングについては、次の記事で別途説明するので、パスします。

次のステップは、応答ヘッダーを設定し、HTTP ヘッダーが送信されたかどうかを検出することです。これは非常に重要ですが、あまり公開されない知識ポイントでもあります。

  • headers_sent(): HTTP ヘッダーが送信されたかどうかを検出します
  • http_response_code(): 応答の HTTP ステータス コードを取得/設定します
  • header: 関数は元の HTTP ヘッダーをクライアントに送信します。
检测 HTTP 头是否已经发送
HTTPヘッダーが送信されたかどうかを確認します

最後のステップ、来て、来て、エコーを伴ってメソッドを実行します$this->sendData($data);

法律は義母になりましたついに終着点に到着したように感じ、エコーは数十日間の悲しみを出力しました!

このエコーカカに到達するために、私たちは9981の困難を乗り越えてきました!戦いはまだ終わっていない、仲間たちはまだ頑張らなければなりません!

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
出力データ

そこで、ここではフレームワークの実行、次にアプリケーションの初期化、ルート検出、コントローラーのインスタンス化、そして応答インスタンスに戻り、エントリーファイルを介して send メソッドを実行します。

最後にデータを端末に出力します。これがエコーです。

ここでの戦いは終わりましたが、以下に非常に重要な知識ポイントがまだあり、カカはそれを説明するためにもう一度言及します。

2. fastcgi_finish_request メソッドが巧みに使用されています

前のセクションで渡された 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秒,但是用户是没有感知的,用户点击发送邮件之后直接就返回发送成功,浏览器响应结束,用户做其它事情,后台进程继续执行发送邮件的任务。

案例

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能

具体代码

<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;">&#39;D:/phpstudy_pro/WWW/kaka.txt&#39;</span>;<br/>    file_put_contents($path,<span class="hljs-string" style="color: #98c379; line-height: 26px;">&#39;程序运行开始&#39;</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;">&#39;程序运行结束&#39;</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;">&#39;任务开始&#39;</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>
ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能

以上测试全部使用linux系统进行测试哈,否则你看不到直观的效果。

经过上面的演示,响应非常快,浏览器响应结束后,后台程序依然进行执行每秒执行一个时间戳。

以上就是对fastcgi_finish_request

理解🎜🎜 この関数の理解は、実際にブラウザに応答を送信することです。ユーザーは長時間待つ必要がありますが、PHP プロセスはまだ実行中です。 🎜🎜これにより、私たちがよく非同期実行と呼ぶものと同様の目的が達成されます。 🎜🎜 直感的に言えば、メールの送信には 10 秒かかるかもしれませんが、ユーザーがメールの送信をクリックすると、送信成功が直接返され、ブラウザーの応答が終了し、ユーザーはその他の操作を行います。バックグラウンドプロセスが電子メールの送信を続行します。 🎜🎜ケース🎜
ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
Figure>🎜特定のコード🎜rrreee
ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
デモンストレーション結果
🎜上記のテストはすべて Linux システムを使用して実行されました。そうでない場合は、直感的な効果がわかりません。 🎜🎜上記のデモの後、応答は非常に速くなります。ブラウザーが応答した後も、バックグラウンド プログラムは毎秒タイムスタンプを実行します。 🎜🎜上記は fastcgi_finish_request メソッドは簡単な紹介、もし興味があれば、ちょっとした秘密をより深く理解するのに役立つ簡単な試してみることができます。 🎜

3. 特性の特徴の説明

カカは2年前にこの特徴を分析したはずです

それはよくスーパークラスと呼ばれます。 trait

この機能は PHP5.4 でのみ追加されました。この機能は頻繁に使用されるインターフェイスでもクラスでもありません。

この機能は、単一継承しかできないという PHP の大きな弱点を解決するものですが、より厳密な関数は多重継承と同じです。

次に事例をご紹介します。

テストファイル1を作成し、対応するクラス名を返します。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能スーパークラス
の最初のファイルはtest1ファイルを作成し、対応するクラス名を返します

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能 スーパークラス
の2番目のファイルは情報を出力するコントローラーファイルを作成します。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能 コントローラー
を作成し、対応するスーパー クラス ファイルをコントローラーに導入します。ここで注意する必要があるのは、最初の丸で囲まれたボックスがスーパー クラス テスト ファイルを直接導入することです。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能対応するスーパークラスファイルをコントローラーに導入します
その後、それに直接アクセスして、何が返されるかを確認できます。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
結果を返す

上の図から、メソッドが Test スーパー クラス ファイルを返すことがわかりますが、このコントローラーは、この記事の冒頭で説明したスーパー クラスであるコントローラー コントローラーにも基づいています。多重継承の関数を実装するだけです。

しかし、ここで問題が発生します。以下のエラーメッセージを参照してください。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
エラー メッセージ

上の図のエラー メッセージは、コントローラーで 2 つのスーパー クラスを使用することによって発生します。これは、下の図でどのように使用されているかです。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
コントローラーは 2 つのスーパークラスを使用します

それでは、このエラー メッセージを解決する方法を説明します。次に、このクリックのリズムに従います。

エラーメッセージの解決

前の問題を解決する前に、まずこの問題の原因を理解する必要があります。

このエラーの理由は、参照されている 2 つの特性に同じ名前の hello 関数があり、競合が発生しているためです。

しかし、メソッド名を手動で変更するのは依然として非常に便利なので、この状況は日常の開発では回避できますが、ここで Kaka がこの問題の解決方法を教えます。

1 つ目は、あるトレイトで hello メソッドを使用して、別のトレイトの同じ名前のメソッドを上書きすることです。2 つのメソッドの内容は一貫しているため、ここで上書きする代わりに、直接選択します。競合が起こらないよう、エイリアスとして as を付けます。 as キーワードには、メソッドのアクセス制御を変更するという別の用途もあります。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
ソリューションの実装

上の図を変更した後、再度アクセスして、返された結果を確認してください。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
結果を返す

次に、この時点で一部のパートナーから質問があるでしょう。つまり、ケースの出力結果は常に Test クラスのメソッドであり、Test1 クラスのメソッドは出力されていません。

それでは訪問方法を説明します!見てみましょう。

ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
スーパークラス2にアクセスするコード

上の図から、アクセス方法がエイリアス制御アクセスに変更されたことがわかります。次に、アクセス結果を見てみましょう。

超类二ThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能
スーパークラス 2 の戻り結果

上の図からわかるように、戻り結果はスーパークラス Test1 の戻り結果です。

そのため、as の使用に関しては、詳細に注意して使用方法を検索する必要がある場合があります。

概要

コントローラーのソースコード分析については、Kaka がソースコードを通じてコン​​トローラーがどのようにインスタンス化されるかを分析します。

ArrayAccess とマジック メソッドの呼び出し関係についても再度説明しました。この問題を考えるには、独自の考え方が必要です。

コントローラーなどにアクセスした後のデータの応答方法です。

ソースコードでの fastcgi_finish_request メソッドの賢い使い方についても学びましたが、この関数を使用する場合は、Kaka について述べた 2 つの点に注意する必要があります。

最後に、スーパークラスの簡単なケースの説明があります。

学習への粘り強さ、ブログへの粘り強さ、そして共有への粘り強さは、カカがキャリア以来貫いてきた信念です。巨大なインターネット上のカカの記事が少しでもお役に立てれば幸いです。」カカ、次号でお会いしましょう

以上がThinkPHP フレームワークで使用される fastcgi_finish_request と trait の機能の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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