ホームページ >バックエンド開発 >PHPチュートリアル >PHP の基本チュートリアル PHP ページのバッファリングのメカニズム
PHPは実はたくさんの仕組みや機能があり、繰り返し使うと簡単な応用でも魔法のような効果が現れます。 Band of Brothers PHP トレーニング
ここでは ob_start() 関数について説明します。
ob_start() 関数はバッファを開くために使用されます。たとえば、header() 関数の前にキャリッジリターン、スペース、改行を含む出力がある場合、「ヘッダーはすべて送信の準備ができていました」というエラーが発生します。この場合、最初に ob_start() を使用して開くことができます。バッファ PHP コードのデータ ブロックと echo() 出力はバッファに入りますが、すぐには出力されません。もちろん、バッファを開くと、多くの処理が行われます。関数については想像力を働かせてください。要約すると次の 4 つです:
1. header( before ();//すべてのコンテンツをブラウザに出力します
?>
2. phpinfo() 関数クライアント側とサーバー側の情報を取得できますが、クライアント側の情報を保存するには、バッファメソッドが最適です。
phpinfo(); // phpinfo 関数を使用します。 $info=ob_get_contents(); //バッファの内容を取得して$infoに代入
$file=fopen( 'info.txt','w');//ファイルinfo.txtを開く
fwrite ($file,$info); //info.txtに情報を書き込む
fclose($file); //info.txtを閉じる
?> 3. 静的ページ技術
ob_start(); //バッファを開く
?>
PHPページの全出力
$content =ob_get_contents();//PHPページが出力した全コンテンツを取得
$fp =fopen("output00001.html", "w"); //ファイルを作成して開き、書き込みの準備をします
fwrite($fp, $content); //PHP ページの内容をすべて Output00001.html に書き込みます。
fclose($fp);
?>
4. 出力コード
関数 run_code($code) {
eval($code);
$contents =ob_get_contents();
ob_end_clean();
echo "エラー! 出力なし"
return $contents;
}
出力制御機能により、スクリプト内のデータの出力を自由に制御できます。特にデータ出力後にファイルヘッダーを出力したい場合に非常に便利です。出力制御関数は、header() または setcookie() を使用して送信されるファイル ヘッダー情報には影響せず、echo() および PHP コードと同様のデータ ブロックにのみ影響します。
OutputControl の全体的な印象を与えるために、簡単な例を示します。
例 1.
CODE
ob_start(); //バッファを開きます
echo ”Hellon”; / /Output
header(”location:index.php”);//ブラウザをindex.phpにリダイレクトします
ob_end_flush();//すべてのコンテンツをブラウザに出力します
?> ヘッダーのすべてのペア() 関数は、この関数がファイル ヘッダーをブラウザに送信することを認識していますが、この関数を使用する前に出力 (スペース、キャリッジ リターン、ライン フィードなどの空の出力を含む) がある場合は、エラーが表示されます。最初の行の ob_start() を削除してこのプログラムを再度実行すると、「ヘッダーはすべて送信準備ができました」というエラー メッセージが表示されることがわかります。ただし、ob_start を使用すると、バッファーがエリアをオンにすると、echo 後の文字はブラウザには出力されませんが、flush または ob_end_flush を使用するまで出力されないため、ファイル ヘッダーの出力にエラーは発生しません。 1. 関連関数の紹介:
1. フラッシュ: バッファの内容を更新して出力します。
関数形式:flush()
説明:この関数は頻繁に使用され、非常に効率的です。
2. ob_start: 出力バッファをオープンします
関数形式: void ob_start(void)
説明: バッファがアクティブ化されると、PHP プログラムからのファイル以外のヘッダー情報はすべて送信されませんが、次の場所に保存されます。内部緩衝地区。バッファの内容を出力するには、ob_end_flush() または flash() を使用してバッファの内容を出力します。
3. ob_get_contents: 内部バッファの内容を返します。
使用法: stringob_get_contents(void)
説明: この関数は、出力バッファがアクティブ化されていない場合、現在のバッファの内容を返します。
4. ob_get_length: 内部バッファの長さを返します。
使用法: intob_get_length(void)
説明: この関数は、出力バッファーがアクティブ化されていない場合、ob_get_contents と同じように現在のバッファーの長さを返します。その後、FALSE を返します。
5. ob_end_flush: 内部バッファの内容をブラウザに送信し、出力バッファを閉じます。
使用法: voidob_end_flush(void)
説明: この関数は、出力バッファーの内容 (存在する場合) を送信します。
6. ob_end_clean: 内部バッファの内容を削除し、内部バッファをクローズします
使用方法: voidob_end_clean(void)
説明: この関数は内部バッファの内容を出力するのではなく、内部バッファを削除します
7 , ob_implicit_flush: 絶対リフレッシュをオンまたはオフにします
使用方法: void ob_implicit_flush([int flag])
説明: Perl を使用したことがある人なら誰でも、この文字列は $|=x の意味を知っています。 ob_implicit_flush 関数は、その関数と同じです。デフォルトでは、絶対出力をオンにした後、各スクリプト出力がブラウザーに直接送信され、flush() を呼び出す必要はありません
2.深さの理解:
1. Flush 関数について:
この関数は PHP3 で登場しました。これは、ブラウザのキャッシュをリフレッシュする非常に便利な関数です。
例 2 .
CODE
for($i = 1; $i <= 300;$i++ ) print(" "); // この文は非常に重要です。キャッシュの構造上、その内容はブラウザから出力されるまでに一定のサイズに達する必要があります
// つまり、キャッシュの内容が一定のサイズに達していない場合、プログラムが実行される前に出力されません。
// テストの結果、このサイズの下限は 256 文字であることがわかりました。これは、今後キャッシュによって受信されるコンテンツが継続的に送信されることを意味します。
For($j = 1; $j <= 20;$j++) {
echo $j.”
flush();絞り出してブラウザ上に表示します
sleep(1); // プログラムを 1 秒間「スリープ」させて、効果をより明確に確認できるようにします
?>具体的な効果はこちらをご覧ください http://www.php2000.com/~uchinaboy/out.php
PHP2000 の最新の PHP チャット ルームでは、残念ながらソース コードが公開されていません。 : プログラム内の場合 ob_implicit_flush() を最初の部分に追加して、絶対リフレッシュをオンにすると、プログラム内でフラッシュ() を使用できなくなります。これによる利点は次のとおりです。
2. ob シリーズの関数について。 :
まず私の親友 y10k を引用したいと思います 例:
例 3.
例えば、サーバーとクライアントの設定情報を使用できますが、この情報はクライアントによって異なりますphpinfo() 関数の出力を保存したい場合はどうすればよいでしょうか? バッファリングを使用しない場合、領域制御を使用する前はまったく解決策がなかったと言えますが、バッファー制御を使用すると簡単に解決できます:
CODE php
ob_start(); // バッファをオープンします
phpinfo(); // phpinfo関数を使用します
$info=ob_get_contents() // バッファの内容を$infoに代入します
$ file=fopen('info.txt','w'); //ファイル info.txt を開く
fwrite($file,$info) //info.txt に情報を書き込む
fclose($file); // ファイル info.txt を閉じます
?>
上記の方法を使用すると、ユーザーの phpinfo 情報が保存されますが、実際には、上記の方法はありませんでした。いくつかの「プロセス」を「関数」に変換する方法です!
「これだけですか? 他に何かあるのですか? もちろんあります。たとえば、著者のフォーラムにある PHP 構文の強調表示は次のとおりです。」これに関連して (PHP のデフォルトの構文強調表示機能は直接出力するため、結果を保存できません。呼び出すたびに表示されると CPU の無駄になります。作者のフォーラムでは、構文強調表示機能によって表示された結果を、バッファの制御) 興味がある場合は、http://www.zphp.com/bbs/ をご覧ください。おそらく誰もが興味を持っているでしょう。ob_start() の関数についてはある程度理解できました。上記の例は単純に見えるかもしれませんが、実際には ob_start() の使用の重要なポイントをマスターしています。
<1>. ob_start を使用してブラウザのキャッシュを開きます。これにより、flush()、ob_end_flush() を呼び出す前 (またはプログラムが実行される前) にキャッシュの内容が出力されなくなります。
< 2> これで、出力コンテンツの後にヘッダー、setcookie、セッションを使用できることがわかりました。これは、ob_start のパラメーターを使用してキャッシュに書き込むこともできます。つまり、ob_start("ob_gzhandler "); などのコマンドが自動的に実行され、最も一般的な方法は、ob_get_contents() を使用してキャッシュ内のコンテンツを取得し、それを処理することです...
<3>。処理が完了したら、flush()、ob_end_flush()、プログラム実行後の自動出力など、様々な方法で出力することができます。もちろん、ob_get_contents() を使用している場合は、出力メソッドを自分で制御する必要があります。
さあ、ob シリーズの関数で何ができるか見てみましょう...
1. 静的テンプレート技術
はじめに: いわゆる静的テンプレート技術とは、何らかのメソッドを使用してユーザーが取得するものを作成することです。クライアント側で PHP HTML ページが生成されます。この HTML ページが更新されなくなると、別のユーザーがこのページを再度閲覧したときに、sina、163、sohu などの大量の情報を含む一部の Web サイトでは、プログラムが PHP および関連データベースを呼び出すことはなくなります。このようなテクノロジーの恩恵は非常に大きいです。
私が知っている静的出力を実現するには 2 つの方法があります:
<1> y10k によって修正された phplib の template.inc.php というクラスを通じて実装されます。
<2>. obシリーズ関数を使用して実装します。
最初の方法については、この記事で検討する問題ではないので、詳細は説明しません。
2 番目のメソッドの具体的な実装を見てみましょう:
例 4.
CODE
ob_start();//バッファを開きます
?>
php のすべての出力page
$content =ob_get_contents();// php ページによって出力されたすべてのコンテンツを取得します
$fp =fopen("output00001.html", "w"); // ファイルを作成し、それを開き、書き込みの準備をします
fwrite($fp, $content); //php ページのすべてのコンテンツを output00001.html に書き込みます、そして...
fclose($fp) ?>
このようにして、いわゆる静的テンプレートが簡単に実装されます...
2. 出力をキャプチャします
上記の例 4 は最も単純なケースです。書き込む前に $content を操作することもできます...
あなたは。例 3 で説明した PHP 構文の強調表示など、いくつかのキーワードを取得して再処理してみます。個人的には、この関数が一番良いところだと思っています。様々な問題を解決できますが、十分な想像力が必要です...
例 5.
CODE<
Function run_code($code? ) {
If($code) {
ob_start();
$contents =ob_get_contents(); echo "エラー! 出力なし"; ();
}
return $contents;
}
上記の例はあまり役に立ちませんが、$code 自体が変数を含む出力ページであることが一般的であり、この例では eval を使用して変数を置き換えます$code で出力をキャプチャし、再度処理します...
例 6. 送信を高速化します
CODE<
ob_start()?
ob_implicit_flush(0 ;
if($ HTTP_ACCEPT_ENCODING , 'x-gzip') !== false) return ”x-gzip”;
if(strpos($HTTP_ACCEPT_ENCODING, 'gzip') !== false) return ”gzip”;
}
functionGzDocOut($level=1,$debug=0){
$ENCODING = CheckCanGzip();
if ($ENCODING){
print ”nn”;
$Contents =ob_get_contents();
ob_end_clean();
if ($debug){
$s = ”
Notcompress length: ”.strlen($Contents); ”
圧縮長: ".strlen(gzcompress($Contents,$level));
$Contents .= $s;
}
header("Content-Encoding:$ENCODING");
print" ×00x00×00x00×00
;$Size = strlen($Contents);
$Crc = crc32($Contents);
$Contents = substr($Contents,0, strlen($Contents) ) – 4);
print $Contents;
print Pack('V',$Size);
ob_end_flush( ; 圧縮が実行され、10,000 を超えるページに影響があることがテストで示されており、ページが大きくなればなるほど、その影響はより顕著になります...