検索
ホームページバックエンド開発PHPチュートリアルPHP出力バッファの詳細な紹介(コード例)

この記事では、PHP の出力バッファについて詳しく紹介 (コード例) しています。一定の参考値があります。必要な友人は参照してください。お役に立てば幸いです。

PHP 出力バッファ:
Buffer: は実際にはメモリ アドレス空間です。速度が同期していないデバイス間や優先度の異なるデバイス間でデータを送信するための領域を格納するために使用されます。バッファリングにより、プロセス間の対話の待ち時間が短縮され、低速デバイスからデータが読み取られるときに、高速デバイスの操作プロセスが中断されなくなります。

PHP の出力ストリームには大量のコンテンツが含まれています。通常、開発者が PHP に出力したいテキストです。これらのテキストのほとんどは、echo または printf() 関数を使用して出力されます

1>コンテンツを出力する関数は出力バッファを使用します

これは通常の PHP スクリプトを指します。PHP 拡張機能を開発している場合、使用される関数 (C 関数) は、出力バッファ層を経由せずに直接出力し、SAPI バッファ層に書き込むことができます (PHP ソースに記述することができます) file main /php_output.h これらの C 関数については、API ドキュメントを参照してください)

2>出力バッファは、出力をバッファするために使用される唯一の層ではなく、実際には多くの層のうちの 1 つにすぎません。バッファレイヤーはSAPI(WebまたはCLI)に関連する使用されているものとは異なり、SAPIが異なる場合があります。

3>SAPI の出力バッファー、これらは PHP のレイヤーです。出力バイトが PHP を出てコンピューター アーキテクチャの下位レイヤーに入ると、バッファー領域が引き続き表示されます (ターミナル バッファー (ターミナル バッファー)、 fast-cgi バッファ、Web サーバー バッファ、オペレーティング システム バッファ、TCP/IP スタック バッファなど)。

PHP CLI の SAPI は少し特殊です。CLI はコマンド ライン インターフェイスとも呼ばれます。これは、php.ini 設定の Output_buffer オプションを 0 に強制します。これは、デフォルトの PHP 出力バッファが無効になることを意味します。 CLI、デフォルトでは、手動で ob_() クラス関数を呼び出さない限り、出力されるコンテンツは SAPI 層に直接渡され、CLI では implicit_flush の値も 1, に設定されます。注: PHP の implicit_flush の役割はよく混同されます。ソース コードがすべてを物語っています。implicit_flush が on (値 1) に設定されている場合、出力は SAPI バッファに書き込まれるとすぐにフラッシュされます (flush、つまりデータを下位層に書き込むと、バッファがクリアになります)

つまり、データが CLI SAPI に送信されると、CLI SAPI はデータをすぐに次の層 (通常は標準出力) に転送します。 Pipe、write()、fflush() 関数はこれを実行する役割を果たします

デフォルトの PHP 出力バッファ

: PHP-FPM など、CLI とは異なる SAPI を使用する場合、次の 3 つのバッファ関連のものが使用されます php.ini 設定オプション

Output_buffering
implicit_flush
Output_handler
まず第一に、ini_set() 関数を使用して値を変更することはできません。これらの値は、PHP プログラムの開始時に変更されるため、実行時にこれらのオプションが変更されます。スクリプトを実行する前に解析されるため、ini_set() を使用して実行時に値を変更できますが、有効になりません。 。それらの値を変更できるのは、php.ini ファイルを編集するか、PHP プログラムの実行時に -d オプションを使用することによってのみです。

デフォルトでは、PHP ディストリビューションは、その値が php.ini セクションの Output_buffering を 4096 ワードに設定します。は ON に設定されており、デフォルトの出力バッファ サイズは 16KB です。

Web アプリケーション環境で出力コンテンツにバッファを使用すると、パフォーマンスが向上します。:
デフォルトの 4K 設定は、適切な値です。まず 4096 個の ASCLL 文字を記述し、次にその下の SAPI 層と通信し、Web アプリケーション環境のソケットを介してメッセージをバイト単位で送信できます。この方法はパフォーマンスに良くありません。より良い方法は、すべてのコンテンツを転送することです。一度にサーバーに送信するか、少なくとも部分的に転送します レイヤー間のデータ交換の数が少ないほど、パフォーマンスは向上しますが、これは常に維持される必要があります 出力バッファーが利用可能であり、PHP がその内容の送信を担当しますリクエストの完了後にエンド ユーザーに送信されます。開発者は何もする必要はありません

Implicit_flush はデフォルトでオフに設定されているため、新しいデータの書き込みによって SAPI はリフレッシュされません。FastCGI プロトコルの場合、リフレッシュ操作は各書き込みの後に FastCGI 配列パケットを送信することです。FastCGI 配列パケットが送信前に送信される場合は、データパケット バッファがいっぱいの方が良いでしょう。 SAPI バッファを手動でリフレッシュする必要がある場合は、flush() 関数を使用します。リフレッシュを書き込む場合は、implicit_flush を設定するか、ob_implicit_flush() 関数を 1 回呼び出します。
推奨構成:
Output_buffering=4096
implicit_flush = Off/no
出力バッファのサイズを変更するには、必ず 4/8 の倍数 (それぞれ 32/64 ビット オペレーティング システム) の値を使用してください

Output_handler は、バッファを更新する前にバッファ内の内容を変更するで使用できるコールバック関数です。

バッファ内の内容は、コールバック関数に渡されます。コンテンツ変換を実行するための選択肢 (1 つだけ使用可能) なので、PHP が Web サーバーとユーザーに提供するコンテンツを取得したい場合は、出力バッファー コールバックを使用できます。出力は、メッセージ ヘッダー、メッセージ ヘッダーを参照します。 。 HTTP メッセージ ヘッダーも出力バッファ層の一部です
メッセージ ヘッダーとメッセージ本文:
実際、メッセージ ヘッダーの出力に関連するすべての PHP 関数 (header()、setcookie) () 、 session_start()) はすべて内部 sapi_header_op 関数を使用し、内容をメッセージ ヘッダー バッファーに書き込むだけです。 printf() 関数を使用すると、内容は最初に出力バッファ (おそらく複数) に書き込まれます。出力リング領域の内容を送信する必要がある場合、PHP は最初にメッセージ ヘッダーを送信し、次にメッセージ本文を送信します。 。 PHP ですべてを処理するには、自分で行う場合は、出力バッファを無効にすることしかできません。

ユーザー出力バッファ:

デフォルトの PHP 出力バッファ層を使用する場合、このレイヤーが無効になっているため、CLI だけは使用できません

/*launched via php -d output_buffering=32 -d implicit_flush=1 
 * */
echo str_repeat('a',31);
sleep(3);
echo 'b';
sleep(3);
echo 'c';
?>

デフォルトの出力バッファ サイズは 32 バイトに設定されています。プログラムの実行中は、最初に 31 バイトが書き込まれ、次にスリープし、次に 1 バイトが書き込まれます。 byte. , このバイトはバッファを埋めます, それはすぐにそれ自体をリフレッシュし, 内部のデータを SAPI 層のバッファに渡します. implicit_flush が 1 に設定されているため, SAPI 層のバッファもすぐに次の層に更新されます, aa...b を出力し、sleep し、バイトを出力します。この時点で、バッファには 31 の空のバイトがありますが、スクリプトが実行されるため、このバイトを含むバッファはすぐに更新され、次の日に出力されます。 c

ユーザー出力バッファ: ob_start() を通じて作成され、そのようなバッファを複数作成できます (メモリが使い果たされるまで)。これらのバッファはスタック構造を形成し、各新しいバッファは画面上にスタックされます。前のバッファでは、バッファがいっぱいになるかオーバーフローするたびにリフレッシュ操作が実行され、データは次のバッファに渡されます

  function callback($buffer)
{
  // replace all the apples with oranges
  return ucfirst($buffer);
}
 function callback1($buffer)
{
  // replace all the apples with oranges
  static $a=0;
  return $a++.'-'.$buffer."\n";
}
ob_start('callback1',10);
ob_start("callback",3);
echo "fo";
sleep(2);
echo 'o';
sleep(2);
echo "barbazz";
sleep(2);
echo "hello";

スタックの先入れ後出しの原則に従って、どの出力も最初にバッファ 2 に保存されます。バッファ 2 のサイズは 3 バイトであるため、最初の echo ステートメントが文字列 'fo' を出力すると、その文字列は最初にバッファ 2 に格納されますが、1 文字が欠けています。2 番目の echo ステートメントが 'o' を出力すると、バッファ 2 はいっぱいになります, それでフラッシュします。 ob_start() のコールバック関数はリフレッシュの前に呼び出されます。この関数はバッファの最初の文字を大文字に変換するため、出力は 'Foo' となり、バッファ 1 に保存され、3 番目の出力は 'barbazz' になります。この文字列は引き続きバッファ 2 に最初に配置されます。この文字列は 7 バイトです。バッファ 2 がオーバーフローしたため、すぐに更新されます。コールバック関数を呼び出して取得した構造体は 'Barbazz' で、バッファ 1 に渡されます。 「FooBarbazz」の文字はバッファ 1 に保存されます。バッファ 1 が更新されます。同様に、ob_start() のコールバック関数が最初に呼び出されます。バッファ 1 のコールバック関数は文字列署名にモデルを追加するため、最初の行はis '0-FooBarbazz',

最後の echo ステートメントは、3 文字を超える文字列 'hello' を出力します。この時点でスクリプトが実行されるため、バッファ 2 がトリガーされます。また、バッファ 1 もすぐにフラッシュされ、「1-Hello」が返されます。

したがって、echo 関数を使用することは非常に簡単なことですが、バッファーやパフォーマンスが関係すると複雑になるため、出力コンテンツのサイズに注意してください。 echoを使用する バッファ構成が出力内容と異なる場合 内容が類似している場合はパフォーマンスが向上します バッファ構成が出力内容より小さい場合、出力内容をアプリケーション内で分割する必要があります。

出力バッファ メカニズム: 主な理由は、バッファ層全体が 5.4 以降に書き換えられたためです。独自の PECL 拡張機能を開発する場合、独自の出力バッファ コールバック メソッドを宣言できるため、区別できます。他の PECL 拡張機能からの競合を避けるため

输出缓冲区的陷阱

      有些PHP的内部函数也使用了输出缓冲区,它们会叠加到其他的缓冲区上,这些函数会填满自己的缓冲区然后刷新,或者返回里面的内容,比如print_r()、higglight_file()和highlight_file::handle()都是此类,所以不应该在输出缓冲区的回调函数中使用这些函数,这样会导致未定义的错误

     同样的道理,当PHP执行echo、print时,也不会立即通过tcp输出到浏览器,而时将数据先写入PHP的默认缓冲区,我们可以理解PHP有一套自己的输出缓冲机制,在传送给系统缓存之前建立一个新的队列,数据经过该队列,当一个PHP缓冲区写满以及脚本执行逻辑需要输出时,脚本会把里面的数据传输给SAPI浏览器

    echo/print->php输出缓冲区->SAPI缓冲区->TCP缓冲区->浏览器缓冲区->浏览器展示

     ob_flush()和flush()区别

        ob_flush():把数据从php的缓冲区中释放出来

        flush():把不再缓冲区中的或者说是被释放出来的数据发送到浏览器,严格来讲, 这个只有在PHP做为apache的Module(handler或者filter)安装的时候, 才有实际作用. 它是刷新WebServer(可以认为特指apache)的缓冲区.

      在nginx中ob_flush和flush两个都失效

        解决办法:  发现在nginx的配置中,有如下的设置

              fastcgi_buffer_size 128k;

     fastcgi_buffers 8 128k;

Nginx会缓冲PHP输出的信息,当达到128k时才会将缓冲区的数据发送给客户端,那么我们首先需要将这个缓冲区调小

比如:

     fastcgi_buffer_size 4k;

     fastcgi_buffers 8 4k;

并且,必须禁用gzip

             gzip off;

然后,在php中,在ob_flushflush前,输出一段达到4k的内容,例如:

            echo str_repeat(‘ ‘, 1024*4);

到此,PHP就可以正常通过ob_flushflush逐行输出需要的内容了。

输出缓冲区实践

    1> 通过ob_start()函数手动处理PHP缓冲区机制,这样即便输出内容超过配置参数大小,也不会把数据传输给浏览器,ob_start()将PHP缓冲区空间设置到足够大,只有脚本执行结束后或调用ob_end_flush()函数,才会把数据发送给浏览器 

for($i=0;$i<10;$i++){
echo $i.&#39;<br/>&#39;;
sleep($i+1);
}

 执行之后不会每隔几秒就有输出,知道脚本循环结束后,才会一次性输出,这是因为数据量太小,输出缓冲区没有写满

2>当修改output_buffering=0

for($i=0;$i<10;$i++){
echo $i.&#39;<br/>&#39;;
flush();
sleep($i+1);
}

 因为缓冲区的容量设置为0,禁用PHP缓冲区机制,这是我们在浏览器看到断断续续输出,而不必等到脚本执行完毕才看到输出,这是因为数据没有在缓存中停留

3>我们把参数修改为output_buffering=4096,输出数据大于一个缓冲区,不调用ob_start()函数

    首先先输出一个4k的内容记下来加本来输出的内容:   

for($i=0;$i<10;$i++){
echo   echo str_repeat(&#39; &#39;, 1024*4*8).$i<br/>;
sleep($i);
}

发现可以HTTP连接未关闭,可以看到间断输出,尽管启用了PHP输出缓冲区机制,但是也不是一次性输出,这还是因为PHP缓冲区空间不够,每写满一个缓冲区,数据就会发送到浏览器。

4>参照上例子,这次我们调用ob_start()

ob_start(); //开启PHP缓冲区
for($i=0;$i<10;$i++){
echo   echo str_repeat(&#39; &#39;, 1024*4*8).$i<br/>;
sleep($i);
}

等到服务端脚本全部处理完,响应结束才会看到完整的输出,在输出前浏览器会一直保持空白,这是因为,PHP一旦调用了ob_start()会将PHP缓冲区扩展到足够大,知道ob_end_flush函数调用或者脚本运行结束才发送PHP缓冲区中的数据到客户端浏览器

  可以通过tcpdump命令监控TCP的报文,来观察一下使用ob_start()和没有使用它的区别

 总结:ob_start激活output_buffering机制,一旦激活,脚本不再直接输出给浏览器,而是先暂时写入PHP缓冲区

            PHP默认开启out_buffering机制,通过调用ob_start函数把output_buffering值扩展到足够大,也可以通过$chunk_size来指定output_buffering的值,$chunk_size默认值是0,表示直到脚本运行结束后,PHP缓冲区中的数据才会发送到浏览器,若设置了$chunk_size的大小,则只要缓冲区达到这个值,就会发送给浏览器你

           可以通过指定output_callback参数来处理PHP缓冲区的数据,比如ob_gzhandler()将缓冲区中的数据压缩后传送给浏览器,ob_get_contents()是获取一份PHP缓冲区中的数据拷贝

ob_start();
echo date(&#39;Y-m-d h:i:s&#39;);

$output=ob_get_contents();
ob_end_flush();
echo &#39;<!output>&#39;.$output;

 后者是从ob_get_contents取的缓冲区的内容

 ob_end_flush()与ob_end_clean(0这两个函数都会关闭输出缓冲,区别是前者只是把PHP缓冲中的数据发生给客户端浏览器,而后者将PHP缓冲区中的数据删掉,但不发送给客户端,前者调用之后数据依然存在,ob_get_contents()依然可以获取PHP缓冲区中的数据拷贝

输出缓冲与静态页面

     大家都知道静态页面的加载速度快,不用请求数据库,以下就是生成静态页面的脚本代码

echo str_pad(&#39;&#39;,1024);//使缓冲区溢出
ob_start();//打开缓冲区
$content=ob_get_contents();//获取缓冲区内容
$f=fopen(&#39;./index.html&#39;,&#39;w&#39;);
fwrite($f,$content);//写入到文件
fclose($f);
ob_end_clean()清空并关闭缓冲区

  在一些模板引擎和页面文件缓冲中ob_start()函数被使用,如 WP、Drupal、Smarty,例如:

在Wp经常在主题目录header.php看到类似的代码:

只有一个flush(),它的所在的位置就是告诉浏览器那一部分的缓存需要更新,即页面头部以上部分需缓存

以及Wp的部分代码,可以看到,在缓冲区开启时,加入自己的回调方法
 内容压缩输出:就是把输出到客户端浏览器的内容进行压缩

好处:降低客户端对服务器出口带宽的占用,提升带宽的利用率。降低Web服务器(如Nginx、Apache、Tomcat等)处理文本时引入的开销,用户端可以减少网络传输延时对用户体验的影响,降低浏览器加载页面内容时占用的内存,有利于改善浏览器稳定性 

ob_start(&#39;ob_gzhandler&#39;);//使用gz格式压缩输出
print&#39;my contents&#39;;
ob_end_flush();

   之压缩当前脚本与缓冲区,对其他脚本没有影响,PHP还提供另外一种压缩方式,在php.ini修改

  zlib_output_compression=On

  这样输出时所有页面都以zlib的压缩方式输出,但是两者混用是毫无意义的,只会额外消耗CPU性能,让它压缩已经压缩好的内容,但是基于实践,使用PHP压缩效果并不是十分理想,通常做法是放在Web服务器,比如Apache启用defate、Nginx使用gzip的方式都比PHP端压缩效果好得多

 输出缓冲允许第三方库和应用框架(Laravel、TP等)开发者完全控制它们自己输出的内容。比如把他们放在一个全局缓冲区中处理,对于任何输出流的内容(如数据压缩)和任何HTTP消息头、PHP都以正确的书序发送,使用输出缓冲区能够有效地节省带宽,比如图片、字体、CSS、JS等前端内容,特别是限制前端框架也越来越来,让它使用户反应速度更快,从而有效提高系统性能

以上がPHP出力バッファの詳細な紹介(コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はCSDNで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
PHPの現在のステータス:Web開発動向を見てくださいPHPの現在のステータス:Web開発動向を見てくださいApr 13, 2025 am 12:20 AM

PHPは、現代のWeb開発、特にコンテンツ管理とeコマースプラットフォームで依然として重要です。 1)PHPには、LaravelやSymfonyなどの豊富なエコシステムと強力なフレームワークサポートがあります。 2)パフォーマンスの最適化は、Opcacheとnginxを通じて達成できます。 3)PHP8.0は、パフォーマンスを改善するためにJITコンパイラを導入します。 4)クラウドネイティブアプリケーションは、DockerおよびKubernetesを介して展開され、柔軟性とスケーラビリティを向上させます。

PHP対その他の言語:比較PHP対その他の言語:比較Apr 13, 2025 am 12:19 AM

PHPは、特に迅速な開発や動的なコンテンツの処理に適していますが、データサイエンスとエンタープライズレベルのアプリケーションには良くありません。 Pythonと比較して、PHPはWeb開発においてより多くの利点がありますが、データサイエンスの分野ではPythonほど良くありません。 Javaと比較して、PHPはエンタープライズレベルのアプリケーションでより悪化しますが、Web開発により柔軟性があります。 JavaScriptと比較して、PHPはバックエンド開発により簡潔ですが、フロントエンド開発のJavaScriptほど良くありません。

PHP対Python:コア機能と機能PHP対Python:コア機能と機能Apr 13, 2025 am 12:16 AM

PHPとPythonにはそれぞれ独自の利点があり、さまざまなシナリオに適しています。 1.PHPはWeb開発に適しており、組み込みのWebサーバーとRich Functionライブラリを提供します。 2。Pythonは、簡潔な構文と強力な標準ライブラリを備えたデータサイエンスと機械学習に適しています。選択するときは、プロジェクトの要件に基づいて決定する必要があります。

PHP:Web開発の重要な言語PHP:Web開発の重要な言語Apr 13, 2025 am 12:08 AM

PHPは、サーバー側で広く使用されているスクリプト言語で、特にWeb開発に適しています。 1.PHPは、HTMLを埋め込み、HTTP要求と応答を処理し、さまざまなデータベースをサポートできます。 2.PHPは、ダイナミックWebコンテンツ、プロセスフォームデータ、アクセスデータベースなどを生成するために使用され、強力なコミュニティサポートとオープンソースリソースを備えています。 3。PHPは解釈された言語であり、実行プロセスには語彙分析、文法分析、編集、実行が含まれます。 4.PHPは、ユーザー登録システムなどの高度なアプリケーションについてMySQLと組み合わせることができます。 5。PHPをデバッグするときは、error_reporting()やvar_dump()などの関数を使用できます。 6. PHPコードを最適化して、キャッシュメカニズムを使用し、データベースクエリを最適化し、組み込み関数を使用します。 7

PHP:多くのウェブサイトの基礎PHP:多くのウェブサイトの基礎Apr 13, 2025 am 12:07 AM

PHPが多くのWebサイトよりも優先テクノロジースタックである理由には、その使いやすさ、強力なコミュニティサポート、広範な使用が含まれます。 1)初心者に適した学習と使用が簡単です。 2)巨大な開発者コミュニティと豊富なリソースを持っています。 3)WordPress、Drupal、その他のプラットフォームで広く使用されています。 4)Webサーバーとしっかりと統合して、開発の展開を簡素化します。

誇大広告を超えて:今日のPHPの役割の評価誇大広告を超えて:今日のPHPの役割の評価Apr 12, 2025 am 12:17 AM

PHPは、特にWeb開発の分野で、最新のプログラミングで強力で広く使用されているツールのままです。 1)PHPは使いやすく、データベースとシームレスに統合されており、多くの開発者にとって最初の選択肢です。 2)動的コンテンツ生成とオブジェクト指向プログラミングをサポートし、Webサイトを迅速に作成および保守するのに適しています。 3)PHPのパフォーマンスは、データベースクエリをキャッシュおよび最適化することで改善でき、その広範なコミュニティと豊富なエコシステムにより、今日のテクノロジースタックでは依然として重要になります。

PHPの弱い参照は何ですか、そしていつ有用ですか?PHPの弱い参照は何ですか、そしていつ有用ですか?Apr 12, 2025 am 12:13 AM

PHPでは、弱い参照クラスを通じて弱い参照が実装され、ガベージコレクターがオブジェクトの回収を妨げません。弱い参照は、キャッシュシステムやイベントリスナーなどのシナリオに適しています。オブジェクトの生存を保証することはできず、ごみ収集が遅れる可能性があることに注意する必要があります。

PHPで__invoke Magicメソッドを説明してください。PHPで__invoke Magicメソッドを説明してください。Apr 12, 2025 am 12:07 AM

\ _ \ _ Invokeメソッドを使用すると、オブジェクトを関数のように呼び出すことができます。 1。オブジェクトを呼び出すことができるように\ _ \ _呼び出しメソッドを定義します。 2。$ obj(...)構文を使用すると、PHPは\ _ \ _ Invokeメソッドを実行します。 3。ロギングや計算機、コードの柔軟性の向上、読みやすさなどのシナリオに適しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)