PHPのob_でstart();ブラウザcacheを制御します!
14305 ワード
【転載】原文住所:http://www.itbbs.cn/index.php?showtopic=1074
Output Control関数は、スクリプト内のデータの出力を自由に制御できます.特に、データが出力された後にファイルヘッダを出力したい場合に便利です.出力制御関数はヘッダ()やsetcookie()を用いず,echo()やPHPコードに類似したデータブロックにのみ影響を及ぼす.
まず簡単な例を挙げて、Output Controlについて大まかな印象を与えましょう.
Example 1.
一、関連関数の紹介:
1、Flush:バッファの内容を更新し、出力する.
関数フォーマット:flush()
説明:この関数はよく使われていて、効率が高いです.
2、ob_start:出力バッファを開く
関数フォーマット:void ob_start(void)
説明:バッファがアクティブになっている場合、PHPプログラムからの非ファイルヘッダ情報はすべて送信されず、内部バッファに保存されます.バッファの内容を出力するにはob_を使用します.end_flush()またはflush()は、バッファの内容を出力します.
3 、ob_ゲットするcontents:内部バッファの内容を返します.
使用方法:string ob_ゲットするcontents(void)
説明:この関数は現在のバッファの内容を返し、出力バッファがアクティブでない場合はFALSEを返します.
4、ob_ゲットするlength:内部バッファの長さを返します.
使用方法:int ob_ゲットするlength(void)
説明:この関数は現在のバッファの長さを返します.およびob_ゲットするcontentsと同様に、出力バッファがアクティブでない場合.FALSEに戻ります.
5、ob_end_flush:内部バッファの内容をブラウザに送信し、出力バッファを閉じます.
使用方法:void ob_end_flush(void)
説明:この関数は出力バッファの内容を送信します(もしあれば).
6、ob_end_Clean:内部バッファの内容を削除し、内部バッファを閉じます.
使用方法:void ob_end_clean(void)
説明:この関数は内部バッファの内容を出力するのではなく、削除します.
7、ob_implicit_flush:絶対リフレッシュをオンまたはオフ
使用方法:void ob_implicit_flush ([int flag])
説明:Perlを使用したことがある人はすべて$|=xの意味を知っていて、この文字列はバッファを開く/閉じることができて、ob_implicit_flush関数もそれと同様に、デフォルトではバッファを閉じ、絶対出力を開くと、各スクリプト出力がブラウザに直接送信され、flush()を呼び出す必要がなくなります.
二、深く理解する:
1.Flush関数について:
この関数はPHP 3に現れ、効率の高い関数であり、browserのcacheをリフレッシュするのに非常に有用な機能を持っている.
Example 2.
2.obシリーズ関数について:
まず私の親友y 10 kの例を引用したいです.
Example 3.
たとえば、サーバとクライアントの設定情報を取得しますが、この情報はクライアントによって異なります.phpinfo()関数の出力を保存したい場合はどうしますか?バッファ制御がない前に、少しも方法がないと言えますが、バッファの制御があれば、簡単に解決できます.
「このままですか?他の用途はありませんか?」と聞かれるかもしれませんが、筆者のフォーラムのPHP文法のハイライト表示はこれと関係があります(PHPのデフォルトの文法ハイライト表示関数はそのまま出力され、結果は保存できません.呼び出すたびに表示されるとCPUがもったいないかもしれませんが、筆者のフォーラムでは文法ハイライト表示の結果をバッファを制御する方法で残しています)、興味があれば見てみましょうhttp://www.zphp.com/bbs/!
今ではob_start()の機能についてある程度知っているかもしれませんが、上記の例では簡単そうに見えますが、実際にはob_start()を使うポイントを把握しています.
<1>.ob_startを使用してbrowserのcacheを開くと、flush()、ob_end_flush()(またはプログラム実行完了)を呼び出す前にcacheの内容が出力されないことを保証できます.
<2>.現在のあなたの強みは、どの出力コンテンツの後ろにもheader、setcookie、sessionを使用できることです.これはob_startの大きな特徴です.ob_startのパラメータを使用して、cacheが書き込まれた後、ob_start(ob_gzhandler)などのコマンドを自動的に実行することもできます.私たちが最もよく使う方法はob_get_contents()です.cacheの内容を入手してから処理して・・・
<3>.処理が完了すると、flush()、ob_end_flush()、およびプログラムの実行が完了するまで待つ自動出力を様々な方法で出力できます.もちろん、ob_get_contents()を使用する場合は、出力方式を自分で制御する必要があります.
では、obシリーズ関数で何ができるか見てみましょう.
一、静的模版技術
概要:静的テンプレート技術とは、クライアント側でPHPによって生成されたhtmlページをユーザが取得できるようにする方法である.このhtmlページが更新されない場合、他のユーザが再びこのページを閲覧すると、プログラムはPHPおよび関連するデータベースを呼び出すことはなく、sina,163,sohuなどの情報量の大きいサイトに対して、このようなの技術がもたらすメリットは非常に大きい.
静的出力を実現するには2つの方法があります.
<1>.y 10 kによって修正されたphplibのtemplate.inc.phpクラスで実現される.
<2>.obシリーズ関数を用いて実現する.
第一の方法については,この文章で検討すべき問題ではないので,これ以上述べない.
2つ目の方法の具体的な実装を見てみましょう.
Example 4.
以上のExample 4.は最も簡単な状況で、書き込む前に$contentを操作することもできます......
Example 3.のPHP構文のハイライト表示など、キーワードをキャプチャして再処理することができます.個人的には、この機能はこの関数の最大のエッセンスであり、さまざまな問題を解決することができますが、十分な想像力が必要です.
Example 5.
Example 6.転送の高速化
Output Control関数は、スクリプト内のデータの出力を自由に制御できます.特に、データが出力された後にファイルヘッダを出力したい場合に便利です.出力制御関数はヘッダ()やsetcookie()を用いず,echo()やPHPコードに類似したデータブロックにのみ影響を及ぼす.
まず簡単な例を挙げて、Output Controlについて大まかな印象を与えましょう.
Example 1.
ob_start(); //
echo "Hellon\"; //
header("location:index.php"); // index.php
ob_end_flush();//
?>
ヘッダー()関数についてよく知っている人は、この関数がブラウザにファイルヘッダを送信することを知っていますが、この関数を使用する前に空の出力(スペース、リターン、改行など)がすでに存在すると、エラーが表示されます.最初の行のobを取り除くとstart()を実行すると、「Header had all ready send by」というエラーメッセージが表示されます.でもob_を加えるとstart、エラーは表示されません.なぜなら、バッファが開いている場合、echoの後ろの文字はブラウザに出力されず、flushまたはob_を使用するまでサーバに保持されるからです.end_flushは出力されるので、ファイルヘッダ出力のエラーはありません!一、関連関数の紹介:
1、Flush:バッファの内容を更新し、出力する.
関数フォーマット:flush()
説明:この関数はよく使われていて、効率が高いです.
2、ob_start:出力バッファを開く
関数フォーマット:void ob_start(void)
説明:バッファがアクティブになっている場合、PHPプログラムからの非ファイルヘッダ情報はすべて送信されず、内部バッファに保存されます.バッファの内容を出力するにはob_を使用します.end_flush()またはflush()は、バッファの内容を出力します.
3 、ob_ゲットするcontents:内部バッファの内容を返します.
使用方法:string ob_ゲットするcontents(void)
説明:この関数は現在のバッファの内容を返し、出力バッファがアクティブでない場合はFALSEを返します.
4、ob_ゲットするlength:内部バッファの長さを返します.
使用方法:int ob_ゲットするlength(void)
説明:この関数は現在のバッファの長さを返します.およびob_ゲットするcontentsと同様に、出力バッファがアクティブでない場合.FALSEに戻ります.
5、ob_end_flush:内部バッファの内容をブラウザに送信し、出力バッファを閉じます.
使用方法:void ob_end_flush(void)
説明:この関数は出力バッファの内容を送信します(もしあれば).
6、ob_end_Clean:内部バッファの内容を削除し、内部バッファを閉じます.
使用方法:void ob_end_clean(void)
説明:この関数は内部バッファの内容を出力するのではなく、削除します.
7、ob_implicit_flush:絶対リフレッシュをオンまたはオフ
使用方法:void ob_implicit_flush ([int flag])
説明:Perlを使用したことがある人はすべて$|=xの意味を知っていて、この文字列はバッファを開く/閉じることができて、ob_implicit_flush関数もそれと同様に、デフォルトではバッファを閉じ、絶対出力を開くと、各スクリプト出力がブラウザに直接送信され、flush()を呼び出す必要がなくなります.
二、深く理解する:
1.Flush関数について:
この関数はPHP 3に現れ、効率の高い関数であり、browserのcacheをリフレッシュするのに非常に有用な機能を持っている.
Example 2.
for($i = 1; $i <= 300; $i++ ) print(" ");
// ,cache
// , cache , 。
// , 256 。 cache
// 。
For($j = 1; $j <= 20; $j++) {
echo $j."
";
flush(); // cache ,
sleep(1); // " " ,
}
?>
注意:プログラムの先頭にob_が追加された場合implicit_flush()絶対リフレッシュを開くと、プログラムでflush()を使用しなくなります.これにより、効率が向上します.2.obシリーズ関数について:
まず私の親友y 10 kの例を引用したいです.
Example 3.
たとえば、サーバとクライアントの設定情報を取得しますが、この情報はクライアントによって異なります.phpinfo()関数の出力を保存したい場合はどうしますか?バッファ制御がない前に、少しも方法がないと言えますが、バッファの制御があれば、簡単に解決できます.
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を使用してbrowserのcacheを開くと、flush()、ob_end_flush()(またはプログラム実行完了)を呼び出す前にcacheの内容が出力されないことを保証できます.
<2>.現在のあなたの強みは、どの出力コンテンツの後ろにもheader、setcookie、sessionを使用できることです.これはob_startの大きな特徴です.ob_startのパラメータを使用して、cacheが書き込まれた後、ob_start(ob_gzhandler)などのコマンドを自動的に実行することもできます.私たちが最もよく使う方法はob_get_contents()です.cacheの内容を入手してから処理して・・・
<3>.処理が完了すると、flush()、ob_end_flush()、およびプログラムの実行が完了するまで待つ自動出力を様々な方法で出力できます.もちろん、ob_get_contents()を使用する場合は、出力方式を自分で制御する必要があります.
では、obシリーズ関数で何ができるか見てみましょう.
一、静的模版技術
概要:静的テンプレート技術とは、クライアント側でPHPによって生成されたhtmlページをユーザが取得できるようにする方法である.このhtmlページが更新されない場合、他のユーザが再びこのページを閲覧すると、プログラムはPHPおよび関連するデータベースを呼び出すことはなく、sina,163,sohuなどの情報量の大きいサイトに対して、このようなの技術がもたらすメリットは非常に大きい.
静的出力を実現するには2つの方法があります.
<1>.y 10 kによって修正されたphplibのtemplate.inc.phpクラスで実現される.
<2>.obシリーズ関数を用いて実現する.
第一の方法については,この文章で検討すべき問題ではないので,これ以上述べない.
2つ目の方法の具体的な実装を見てみましょう.
Example 4.
ob_start();//
?>
php
$content = ob_get_contents();// php
$fp = fopen("output00001.html", "w"); // , ,
fwrite($fp, $content); // php output00001.html, ……
fclose($fp);
?>
二、スナップ出力以上のExample 4.は最も簡単な状況で、書き込む前に$contentを操作することもできます......
Example 3.のPHP構文のハイライト表示など、キーワードをキャプチャして再処理することができます.個人的には、この機能はこの関数の最大のエッセンスであり、さまざまな問題を解決することができますが、十分な想像力が必要です.
Example 5.
Function run_code($code) {
If($code) {
ob_start();
eval($code);
$contents = ob_get_contents();
ob_end_clean();
}else {
echo " ! ";
exit();
}
return $contents;
}
以上の例の用途は大きくないが、典型的には$code自体が変数を含む出力ページであり、この例はevalで$codeの変数を置き換え、出力結果を出力キャプチャし、もう一度処理する......Example 6.転送の高速化
/*
** Title.........: PHP4 HTTP Compression Speeds up the Web
** Version.......: 1.20
** Author........: catoc
** Filename......: gzdoc.php
** Last changed..: 18/10/2000
** Requirments...: PHP4 >= 4.0.1
** PHP was configured with --with-zlib[=DIR]
** Notes.........: Dynamic Content Acceleration compresses
** the data transmission data on the fly
** code by sun jin hu (catoc)
** Most newer browsers since 1998/1999 have
** been equipped to support the HTTP 1.1
** standard known as \"content-encoding.\"
** Essentially the browser indicates to the
** server that it can accept \"content encoding\"
** and if the server is capable it will then
** compress the data and transmit it. The
** browser decompresses it and then renders
** the page.
**
** Modified by John Lim ([email][email protected][/email])
** based on ideas by Sandy McArthur, Jr
** Usage........:
** No space before the beginning of the first \'\' tag.
** ------------Start of file----------
** |
** | include(\'gzdoc.php\');
** |? >
** |
** |... the page ...
** |
** |
** | gzdocout();
** |? >
** -------------End of file-----------
*/
ob_start();
ob_implicit_flush(0);
function CheckCanGzip(){
global $HTTP_ACCEPT_ENCODING;
if (headers_sent() || connection_timeout() || connection_aborted()){
return 0;
}
if (strpos($HTTP_ACCEPT_ENCODING, 'x-gzip\') !== false) return \"x-gzip\";
if (strpos($HTTP_ACCEPT_ENCODING,\'gzip\') !== false) return \"gzip\";
return 0;
}
/* $level = compression level 0-9, 0=none, 9=max */
function GzDocOut($level=1,$debug=0){
$ENCODING = CheckCanGzip();
if ($ENCODING){
print \"nn\";
$Contents = ob_get_contents();
ob_end_clean();
if ($debug){
$s = \"Not compress length: \".strlen($Contents);
$s .= \"
Compressed length: \".strlen(gzcompress($Contents,$level));
$Contents .= $s;
}
header(\"Content-Encoding: $ENCODING\");
print \"x1fx8bx08x00x00x00x00x00\";
$Size = strlen($Contents);
$Crc = crc32($Contents);
$Contents = gzcompress($Contents,$level);
$Contents = substr($Contents, 0, strlen($Contents) - 4);
print $Contents;
print pack(
\'V\',$Crc);
print pack(\'V\',$Size);
exit;
}else{
ob_end_flush();
exit;
}
}
?>
これはcatocの昔のコードで、weblogs.comで見たものです.彼はzlibの関数を利用して、伝送された内容を圧縮しました.テストによると、10 k以上のページには効果があり、ページが大きいほど効果が明らかになります.