【転載】元アドレス: http://www.itbbs.cn/index.php?showtopic=1074
出力制御機能を使用すると、スクリプト内のデータの出力を自由に制御できます。特にデータ出力後にファイルヘッダーを出力したい場合に非常に便利です。出力制御関数は、header() または setcookie() を使用して送信されるファイル ヘッダー情報には影響せず、echo() および PHP コードと同様のデータ ブロックにのみ影響します。
出力制御の一般的な印象を皆さんに伝えるために、まず簡単な例を示しましょう:
例 1.
<span><br><?php <SPAN>ob_start<BR></SPAN>(); <SPAN></SPAN>//バッファを開く <SPAN><BR></SPAN>"Hellon" //出力 <SPAN>header("</SPAN><SPAN>location<BR> </SPAN>: <SPAN></SPAN>インデックス<SPAN> </SPAN> .<SPAN></SPAN>php<SPAN></SPAN>"); //ブラウザをindex.phpにリダイレクトします <SPAN>ob_end_flush();//すべてのコンテンツをブラウザに出力します </SPAN>?> <span> <br><br><br></span>header() 関数を知っている人なら誰でも、この関数がファイル ヘッダーをブラウザに送信することを知っていますが、この関数を使用する前に出力がある場合 (スペース、キャリッジ リターン、ライン フィードなどの空の出力を含む)、エラーが発生します。プロンプトが表示されます。最初の行の ob_start() を削除してこのプログラムを実行すると、次のエラー メッセージが表示されることがわかります。「ヘッダーはすべて送信準備ができました。」ただし、ob_start を使用すると、エラー メッセージは表示されません。その理由は、バッファーが開かれたときに、echo 以降の文字がブラウザーに出力されず、flush を使用するまでサーバー上に出力されないためです。または ob_end_flush なので、ファイル ヘッダー出力エラーは発生しません。 <br>1. 関連機能の紹介: <br>1. フラッシュ: バッファーと出力の内容を更新します。 <br>関数形式: flash() <br>説明: この関数は頻繁に使用され、非常に効率的です。 <br>2. ob_start: 出力バッファを開きます。 <br>関数形式: void ob_start(void) <br>説明: バッファがアクティブ化されると、PHP プログラムからのファイル以外のヘッダー情報はすべて送信されず、内部バッファーに保存されます。 。バッファの内容を出力するには、ob_end_flush() または flash() を使用してバッファの内容を出力します。 <br>3、ob_get_contents: 内部バッファの内容を返します。 <br>使用法: string ob_get_contents(void) <br>説明: この関数は、出力バッファがアクティブ化されていない場合、現在のバッファの内容を返します。 <br>4. ob_get_length: 内部バッファーの長さを返します。 <br>使用法: int ob_get_length(void) <br>説明: この関数は、出力バッファーがアクティブ化されていない場合、ob_get_contents と同様に現在のバッファーの長さを返します。その後、FALSE を返します。 <br>5. ob_end_flush: 内部バッファの内容をブラウザに送信し、出力バッファを閉じます。 <br>使用法: void ob_end_flush(void) <br>説明: この関数は、出力バッファーの内容 (存在する場合) を送信します。 <br>6. ob_end_clean: 内部バッファの内容を削除し、内部バッファを閉じます。 <br>使用法: void ob_end_clean(void) <br>説明: この関数は内部バッファの内容を出力しません。 <br>7. ob_implicit_flush: 絶対フラッシュをオンまたはオフにします。 <br> 使用方法: void ob_implicit_flush ([int flag]) <br> 注: Perl を使用したことのある人なら誰でも、$|=x の意味を知っています。 ob_implicit_flush 関数はその関数と同じです。デフォルトでは、絶対出力をオンにした後、各スクリプト出力がブラウザに直接送信され、<br>2 番目の関数を呼び出す必要はありません。深さの理解: <br>1. フラッシュ関数について: <br> この関数は PHP3 で登場し、ブラウザのキャッシュを更新する非常に便利な関数です。フラッシュを説明するために、非常に明白な操作効果を持つ例を示します。 <br>例 2. <br><br><div class="code"> <code><span><br><?php <SPAN>$i<br></span>++ ) print (<span></span>" "<span></span>)// この文は非常に重要です。 <span>// つまり、キャッシュの内容が一定のサイズに達しない場合、プログラムの実行が完了するまでそのサイズは出力されません。 。 </span>// テストの結果、このサイズの下限は 256 文字であることがわかりました。これは、今後キャッシュによって受信されるコンテンツが <span>// 継続的に送信されることを意味します。 </span>echo <span></span>$j<span> </span>.<span></span>" <span>"</span><span>; </span><span></span>flush<span></span>(); <span></span>// この部分は、新しく追加されたコンテンツをキャッシュから取り出してブラウザに表示します<span><br></span>sleep<span><br>(<br> <br>1<br></span>); <span></span>//プログラムを少しの間「スリープ」させて、効果をより明確に確認できるようにします <span></span><span>} </span><span></span>?><span> </span> <span></span><span><br>注: ob_implicit_flush() をプログラムの先頭に追加して絶対リフレッシュを有効にすると、プログラム内で flash() を使用できなくなります。これによる利点は次のとおりです。効率が向上します。 <br>2. ob シリーズの機能について: <br> まずは私の友人 y10k の例を引用したいと思います: <br>例 3. <br> たとえば、サーバーとクライアントの設定情報を使用できますが、この情報はphpinfo() 関数の出力を保存したい場合はどうすればよいですか?バッファ制御がなかった前は、まったく解決策がなかったと言えますが、バッファ制御を使用すると、次のように簡単に解決できます。 /Open Buffer <br><div class="code">
<code>phpinfo<span><br>(); <span><br>//phpinfo関数を使用します</span><span></span>$info<span><br>=</span><span>ob_get_contents</span><span>(); info </span> <span> <br>$file</span><span>=</span><span>fopen</span><span>('</span><span>info.txt</span><span>'<br></span>,<span></span>'<span></span>w<span></span>'<span></span>); //ファイルinfo.txを開く<span>fwrite( $file, $info); // info.txt に情報を書き込みます </span>fclose($file); // ファイル info.txt を閉じます <span></span><span></span><span></span>;さまざまなユーザーの情報を保存してください。申し訳ありませんが、これまでは不可能でした。実は上記は一部の「処理」を「関数」に変換する方法なのです! <span>「これはただのことですか? 他に用途はあるのですか?」と疑問に思う人もいるかもしれません。もちろん、たとえば、作者のフォーラムの PHP 構文ハイライトはこれに関連しています (PHP のデフォルトの構文ハイライト機能は直接出力します)。呼び出すたびに結果が表示されるとCPUの無駄になりますので、興味のある方は構文強調表示機能で表示された結果を保存しておいてください。 http://www.zphp.com/bbs/ をご覧ください。 </span>これで、ob_start() の関数をある程度理解できたのではないでしょうか。上の例は単純に見えますが、実際には、ob_start() の使用の重要なポイントをマスターしたことになります。 <span><1>. ob_start を使用してブラウザのキャッシュを開くと、flush()、ob_end_flush() を呼び出す前 (またはプログラムが実行される前) にキャッシュの内容が出力されなくなります。 </span><2>. これで、出力コンテンツの後にヘッダー、setcookie、セッションを使用できることがわかりました。これは ob_start の優れた機能であり、ob_start のパラメーターをキャッシュに書き込むこともできます。入力後、ob_start("ob_gzhandler"); などのコマンドを自動的に実行します。最も一般的に使用される方法は、ob_get_contents() を使用してキャッシュ内のコンテンツを取得し、それを処理することです。 <span><3>処理が完了したら、flush()、ob_end_flush()、プログラム実行後の自動出力など、様々な方法で出力することができます。もちろん、ob_get_contents() を使用している場合は、出力メソッドを自分で制御する必要があります。 <br>さあ、ob シリーズ関数で何ができるか見てみましょう... <br>1. 静的テンプレート技術<br> はじめに: いわゆる静的テンプレート技術は、ユーザーが PHP によって生成された HTML ページを取得できるようにするものです。クライアント側で。この HTML ページが更新されなくなると、別のユーザーがこのページを再度参照したときに、プログラムは、sina、163、sohu などの大量の情報を含む一部の Web サイトの PHP および関連データベースを呼び出すことはなくなります。このようなテクノロジーの恩恵は非常に大きいです。 <br>私が知っている静的出力を実現するには 2 つの方法があります: </span>. y10k によって変更された phplib の template.inc.php というクラスを通じて実装されます。 </span><2>. ob シリーズの関数を使用して実装されます。
最初の方法については、この記事で検討する問題ではないため、詳細は説明しません。 2 番目のメソッドの具体的な実装を見てみましょう: <span><? <BR>$content <SPAN><BR>= </SPAN><SPAN>ob_get_contents</SPAN><SPAN>();<BR></SPAN>//PHP ページの出力のすべてのコンテンツを取得 <SPAN></SPAN><BR>$fp <BR><SPAN>= <BR></SPAN>fopen <SPAN></SPAN>( <SPAN></SPAN>"output00001.html"<SPAN></SPAN>, <SPAN><BR>"w"</SPAN><SPAN>); </SPAN><SPAN>//ファイルを作成して開き、書き込みの準備をします </SPAN><SPAN></SPAN>fwrite<SPAN></SPAN>(<SPAN></SPAN>$fp<SPAN></SPAN>, <SPAN>) </SPAN>$ content<SPAN></SPAN>); <SPAN><BR>//PHP ページのすべてのコンテンツを Output00001.html に書き込み、次に... </SPAN><SPAN></SPAN>fclose<SPAN></SPAN>(<SPAN></SPAN>$fp<SPAN></SPAN>); <SPAN></SPAN><SPAN><br>2. 出力をキャプチャする <BR> 上記の例 4. は最も単純なケースです。書き込む前に $content を操作することもできます。 <BR> たとえば、次で説明されている PHP 構文の強調表示を試みることもできます。例 3.個人的には、この関数がさまざまな問題を解決できる最も優れた部分だと思いますが、十分な想像力が必要です... <BR><BR><DIV class=code><CODE><SPAN><? <BR><SPAN>run_code<BR></SPAN>(<SPAN></SPAN>$code<SPAN></SPAN>) { <SPAN>If(</SPAN><SPAN>$code</SPAN><SPAN>) { <BR></SPAN><SPAN>ob_start</SPAN><SPAN>(); ; <BR></SPAN><SPAN>$コンテンツ</SPAN><SPAN>= <BR></SPAN>ob_get_contents<SPAN></SPAN>(); <SPAN><BR></SPAN>ob_end_clean<SPAN></SPAN>(); <SPAN>echo </SPAN><SPAN>「エラー! 出力がありません」 </SPAN>exit(); <SPAN>} <BR>戻る </SPAN><SPAN>$contents </SPAN><SPAN>; <BR>} <BR></SPAN><SPAN></SPAN><br>上記の例はあまり役に立ちませんが、$code 自体が変数を含む出力ページであることが一般的です。この例では、$code 内の変数を置き換えるために eval が使用され、出力結果が再度取得されます。 ..<br>例 6. 加快传输 <br><DIV class=code><CODE><SPAN><BR><SPAN><? <BR></SPAN><SPAN>/* <BR>** タイトル.....: PHP4 HTTP Compression Speeds the Web <BR>** バージョン....: 1.20 <BR>** 著者.... .: catoc <[email]catoc@163.net[/email]> <br>** ファイル名....: gzdoc.php <br>** 最終変更日..: 18/10/2000 <br>** 要件...: PHP4 >= 4.0.1 <br>** PHP は - で構成されました-with-zlib[=DIR] <br>** 注意....................: ダイナミック コンテンツ アクセラレーションは、<br>** データ送信データをその場で圧縮します <br>** コード by sun jin hu (catoc) <[ [メール]catoc@163.net[/メール]> <BR>** 1998/1999 年以降のほとんどの新しいブラウザには、「コンテンツ エンコーディング」として知られる HTTP 1.1 <BR>** 標準をサポートする機能が搭載されています。 <BR>** 基本的に、ブラウザは <BR>** サーバーに「コンテンツ エンコーディング」 <BR>** を受け入れることができることを示し、サーバーが対応できる場合は、 <BR>** データを圧縮して送信します。 <BR>** ブラウザはそれを解凍し、その後、ページを <BR>** レンダリングします。 <BR>** <BR>** John Lim ([email]jlim@natsoft.com.my[/email]) によって変更されました <BR>** Sandy McArthur, Jr のアイデアに基づいています <BR>** 使用法....: <BR>** 最初の「<?」の先頭の前にスペースは入れません。 鬼ごっこ。 <BR>** -----------ファイルの開始---------- <BR>** |<? <BR>** | include('gzdoc.php'); <BR>** |? > <BR>** |<HTML> <BR>** |... ページ ... <BR>** |</HTML> <br>** | <br>** | gzdocout(); <br>** |? > <br>** ---------------ファイルの終わり----------- <br>*/ <br><br></span>ob_start<span></span>(); <span><br></span>ob_implicit_flush<span></span>(<span></span>0<span></span>); <span>関数 <br></span>CheckCanGzip<span></span>(){ <span>グローバル <br></span>$HTTP_ACCEPT_ENCODING<span></span>; <span>if (<br></span>headers_sent<span></span>() || <span></span>connection_timeout<span></span>() || <span></span>connection_aborted<span></span>()){ <span>return <br></span>0<span></span>; <span>} <br>if (<br></span>strpos<span></span>(<span></span>$HTTP_ACCEPT_ENCODING<span></span>, '<span></span>x-gzip<span></span>'<span></span>) !== false) return "x-gzip"; <span>if (strpos($HTTP_ACCEPT_ENCODING,<br></span>'<span></span>gzip<span></span>'<span></span>) !== false) return "gzip"; <span>0を返す; <br>} <br>/* $level = 圧縮レベル 0-9、0=なし、9=最大 */ <br>function GzDocOut($level=1,$debug=0){ <br>$ENCODING = CheckCanGzip(); <br>if ($ENCODING){ <br>print "n<!-- Use compress $ENCODING -->n"; <BR>$Contents = ob_get_contents(); <BR>ob_end_clean(); <BR>if ($debug){ <BR>$s = "<p>長さを圧縮しません: ".strlen($Contents); <BR>$s .= " <BR>圧縮された長さ: ".strlen(gzcompress($Contents,$level)); <BR>$Contents .= $s; <BR>} <BR>header("Content-Encoding: $ENCODING"); <BR>「x1fx8bx08x00x00x00x00x00」を印刷します。 <BR>$サイズ = strlen($Contents); <BR>$Crc = crc32($Contents); <BR>$Contents = gzcompress($Contents,$level); <BR>$Contents = substr($Contents, 0, strlen($Contents) - 4); <BR>$Contents を印刷します。 <BR>プリントパック(<BR></SPAN>'<SPAN></SPAN>V<SPAN></SPAN>'<SPAN></SPAN>,$Crc); <SPAN>プリントパック(<BR></SPAN>'<SPAN></SPAN>V<SPAN></SPAN>'<SPAN></SPAN>,$Size); <SPAN>終了; <BR>}else{ <BR>ob_end_flush(); <BR>終了; <BR>} <BR>} <BR>?> <br><br></span>
上記では、PHP の ob_start; を使用してブラウザのキャッシュを制御する方法を紹介しました。内容の側面も含めて、PHP チュートリアルに興味のある友人に役立つことを願っています。