[轉載]用PHP的ob_start();控制您的瀏覽器cache!

FROM http://www.phpchina.com/html/28/1628-3870.html

Output Control 函數可以讓你自由控制腳本中數據的輸出。它非常地有用,特別是對于:當你想在數據已經輸出后,再輸出文件頭的情況。輸出控制函數不對使用 header() 或 setcookie(), 發送的文件頭信息產生影響,只對那些類似于 echo() 和 PHP 代碼的數據塊有作用。

我們先舉一個簡單的例子,讓大家對Output Control有一個大致的印象:
Example 1.

CODE<?php
ob_start(); //打開緩沖區
echo \"Hellon\"; //輸出
header("location:index.php"); //把瀏覽器重定向到index.php
ob_end_flush();//輸出全部內容到瀏覽器
?>

所有對header()函數有了解的人都知道,這個函數會發送一段文件頭給瀏覽器,但是如果在使用這個函數之前已經有了任何輸出(包括空輸出,比如空格,回車和換行)就會提示出錯。如果我們去掉第一行的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_get_contents :返回內部緩沖區的內容。
使用方法:string ob_get_contents(void)
說明:這個函數會返回當前緩沖區中的內容,如果輸出緩沖區沒有激活,則返回 FALSE 。
4、ob_get_length:返回內部緩沖區的長度。
使用方法:int ob_get_length(void)
說明:這個函數會返回當前緩沖區中的長度;和ob_get_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函數:
這個函數在PHP3中就出現了,是一個效率很高的函數,他有一個非常有用的功能就是刷新browser的cache.我們舉一個運行效果非常明顯的例子來說明flush.
Example 2.

CODE<?php
for($i = 1; $i <= 300; $i++ ) print(" ");
// 這一句話非常關鍵,cache的結構使得它的內容只有達到一定的大小才能從瀏覽器里輸出
// 換言之,如果cache的內容不達到一定的大小,它是不會在程序執行完畢前輸出的。經
// 過測試,我發現這個大小的底限是256個字符長。這意味著cache以后接收的內容都會
// 源源不斷的被發送出去。
For($j = 1; $j <= 20; $j++) {
echo $j."
";
flush(); //這一部會使cache新增的內容被擠出去,顯示到瀏覽器上
sleep(1); //讓程序"睡"一秒鐘,會讓你把效果看得更清楚
}
?>


具體效果你可以到這里看看http://www.php2000.com/~uchinaboy/out.php
PHP2000的最新的PHP聊天室就是用的這個技術,可惜的是源代碼未公開 L
注:如果在程序的首部加入ob_implicit_flush()打開絕對刷新,就可以在程序中不再使用flush(),這樣做的好處是:提高效率!

2. 關于ob系列函數:
我想先引用我的好朋友y10k的一個例子:
Example 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打開browser的cache,這樣可以保證cache的內容在你調用flush(),ob_end_flush()(或程序執行完畢)之前不會被輸出。
<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系列函數做些什么……

一、 靜態模版技術

簡介:所謂靜態模版技術就是通過某種方式,使得用戶在client端得到的是由PHP產生的html頁面。如果這個html頁面不會再被更新,那么當另外的用戶再次瀏覽此頁面時,程序將不會再調用PHP以及相關的數據庫,對于某些信息量比較大的網站,例如sina,163,sohu。類似這種的技術帶來的好處是非常巨大的。

我所知道的實現靜態輸出的有兩種辦法:
<1>.通過y10k修改的phplib的一個叫template.inc.php類實現。
<2>.使用ob系列函數實現。
對于第一種方法,因為不是這篇文章所要研究的問題,所以不再贅述。
我們現在來看一看第二種方法的具體實現:
Example 4.


CODE<?php
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.

CODE<?
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. 加快傳輸


CODE<?
/*
** Title.........: PHP4 HTTP Compression Speeds up the Web
** Version.......: 1.20
** Author........: catoc <[email]catoc@163.net[/email]>
** 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) <[email]catoc@163.net[/email]>
** 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]jlim@natsoft.com.my[/email])
** based on ideas by Sandy McArthur, Jr
** Usage........:
** No space before the beginning of the first \'<?\' tag.
** ------------Start of file----------
** |<?
** | include(\'gzdoc.php\');
** |? >
** |<HTML>
** |... the page ...
** |</HTML>
** |<?
** | 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 \"n<!-- Use compress $ENCODING -->n\";
$Contents = ob_get_contents();
ob_end_clean();
if ($debug){
$s = \"<p>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的函數,對傳輸的內容進行了壓縮,測試表明,對于10k以上的頁面,會產生效果,而且頁面越大,效果越明顯……

?

?

ExpandedBlockStart.gif代碼
????ob_start();?
????
$sql?=?"SELECT?*?FROM?table?ORDER?BY?theme_id?asc";
????
$rst?=?$db->query($sql);
????
while($row?=?$db->fetch_array($rst))
????{
????????
$theme_id?=?$row[theme_id];

????????
$fromUrl?=?SOFT_HTMLURL."marryphoto.php?handle=theme&theme_id=".$theme_id;
????????
$sendUrl?=?"../html_".$theme_id.".html";

????????@
readfile($fromUrl);???
????????
$htmltext?=?ob_get_contents();
????????
$htmlfile?=?fopen($sendUrl,"w");???
????????
fwrite($htmlfile,$htmltext);???
????????
ob_clean();
????}

????
$fromUrl?=?SOFT_HTMLURL."html.php";
????
$sendUrl?=?"../html.html";
????@
readfile($fromUrl);???
????
$htmltext?=?ob_get_contents();
????
$htmlfile?=?fopen($sendUrl,"w");???
????
fwrite($htmlfile,$htmltext);???
????
ob_clean();

?

?

轉載于:https://www.cnblogs.com/Athrun/archive/2010/05/23/1742121.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276050.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276050.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276050.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

oracle 帶有變量的語句_【成都校區】Oracle SQL語句之常見優化方法總結

本帖出自于黑馬程序員成都中心&#xff0c;更多資源可關注微信公眾號1、SQL語句盡量用大寫的&#xff1b;因為oracle總是先解析SQL語句&#xff0c;把小寫的字母轉換成大寫的再執行。2、使用表的別名&#xff1a; 當在SQL語句中連接多個表時, 盡量使用表的別名并把別名前綴于每…

js 獲取上下文后面的路徑_通過在數據后面顯示上下文來可視化公眾意見

js 獲取上下文后面的路徑In 1824, The Harrisburg Pennsylvanian, a newspaper from a town in Pennsylvania conducted the first known public opinion polls in history, and successfully predicted the result of the vote in the close race between Andrew Jackson and …

甘肅甘南步班郵遞員:草原上的“遞愛”艱途

圖為甘肅甘南藏族自治州碌曲縣郎木寺鎮郵政支局的投遞員進行投遞工作。&#xff08;資料圖&#xff09; 鐘欣 攝 中新網蘭州1月25日電 (吳玉蒿)漸近春節&#xff0c;劉權英投遞郵件的工作愈加繁重。現年45歲的劉權英是甘肅甘南藏族自治州碌曲縣郎木寺鎮郵政支局的一名投遞員。由…

核心編程6——線程

Note 0:了進程實際是由兩個組件組成的:一個進程內核對象和一個地址空間.類似地,線程也由兩個組件組成:一個是線程的內核對象,操作系統用它管理線程.內核對象還是系統用來存放線程統計信息的地方.一個線程堆棧,用于維護線程執行時所需的所有函數參數和局部變量.Note 1:進程是有惰…

PHP解決搶購、秒殺、搶樓、抽獎等阻塞式高并發庫存防控超量的思路方法

轉載鏈接&#xff1a;http://www.4u4v.net/thinking-approach-to-buy-spike-grab-floor-sweepstakes-and-other-high-concurrent-blocking-prevention-excess-inventory-solve-php.html 如今在電商行業里,秒殺搶購活動已經是商家常用促銷手段。但是庫存數量有限&#xff0c;而同…

看了就會的 Node.js 三大基礎模塊常用 API

大家好&#xff0c;我是若川。歡迎加我微信 ruochuan12&#xff0c;加群交流學習。今天分享一篇nodejs基礎的文章。點擊下方卡片關注我&#xff0c;或者查看源碼等系列文章。在日常使用 Node 進行開發的時候&#xff0c;會使用到一些文件系統、路徑操作等基礎 API&#xff0c;這…

vue-cli3插件初體驗

vue-cli3發布自2018年8月&#xff0c;距離現在還不是特別久&#xff0c;最好搭建項目剛好用到&#xff0c;所以寫下這篇文章&#xff0c;記錄一下踩坑經歷。vue的作者說過&#xff0c;vue-cli的本質是模版的拉取&#xff0c;太多的配置導致了模版的難以維護&#xff0c;所以重構…

ios設計登錄功能_親愛的產品設計師,這是iOS 14的新功能

ios設計登錄功能On June 22, 2020 Apple previewed iOS 14 for the first time. As always there are quite some changes you should know about as a product designer like widgets, pickers, app clips, permissions and more.2020年6月22日&#xff0c;Apple首次預覽iOS 1…

c++ int 轉 short_C/C++結構體內存對齊

在面試或工作中&#xff0c;經常會遇到內存對齊的問題。這里結合我的理解談一談對內存對齊的理解。1. 為什么要內存對齊&#xff0c;不對齊會怎么樣&#xff1f;內存中存放數據是為了給CPU使用&#xff0c;CPU訪問內存數據時會受到地址總線寬度的限制&#xff0c;也就是一次能從…

對于日訪問量達到1W IP的處理方法

轉自&#xff1a;http://www.java123.net/56026-2.html 對于日訪問量達到1W IP的處理方法 一、1萬ip真是不高&#xff1a; 1.常用數據用緩存&#xff0c;減輕數據庫壓力。 2.詳細頁數據生成靜態頁面。 二、10000算是相當小的了,不需要什么特殊的處理機制,只要符合最一般的…

數據契約(DataContract)

WCF第一要素就是契約: 服務契約用于聲明可用于遠程訪問的類型。在Interface或class開始處使用服務契約標簽. [ServiceContract] Public interface Iservice { } 接口調用契約的好處: 1. 同一服務類型可以實現多個不相干的服務契約. 2. 有利于版本升級 3. 按照…

jakob slam_Jakob Nielsen針對用戶界面設計的第二種可用性啟發法

jakob slamIn the pursuit of providing great user experiences, it’s imperative that digital products are evaluated. A 為了提供出色的用戶體驗&#xff0c;必須對數字產品進行評估。 一個 heuristic evaluation is essential to delivering great user experiences. I…

微軟Office 365正式上架Mac App Store

今天&#xff0c;Office 365正式在Mac App Store上架&#xff0c;Mac用戶可以輕松下載Word&#xff0c;Outlook&#xff0c;Excel&#xff0c;PowerPoint&#xff0c;OneNote以及整套微軟的熱門應用程序。用戶還可以從應用程序內訂購Office 365。蘋果全球開發者關系高級主管Sha…

一文搞懂瀏覽器原理

大家好&#xff0c;我是若川。最近這幾年&#xff0c;云計算的普及和 HTML5 技術的快速發展&#xff0c;越來越多的應用轉向了瀏覽器 / 服務器&#xff08;B/S&#xff09;架構&#xff0c;這種改變讓瀏覽器的重要性與日俱增&#xff0c;視頻、音頻、游戲幾大核心場景也都在逐漸…

python處理excel可視化_python如何將excel數據處理可視化

python將excel數據處理可視化的方法&#xff1a;首先安裝xlrd與xlwt庫&#xff0c;進行表格讀取&#xff1b;然后使用pyecharts生成Echarts圖表的類庫&#xff1b;最后安裝Echarts讀取Excel數據及顯示即可。python將excel數據處理可視化的方法&#xff1a;Excel表操作python操作…

dataframe中將一列數據切分成多列

為什么80%的碼農都做不了架構師&#xff1f;>>> 原sheet中數據 目的 將【備注】列切分成【key】列和【value】列 Python sheet[key] sheet[備注].str.extract(r(_.*(?\u503c))) sheet[value] sheet[備注].str.extract(r((?<).*))結果 參考 pandas.Series.st…

matplotlib可視化_EDA:Geopandas,Matplotlib和Bokeh中的可視化

matplotlib可視化Nowadays, everyone is immersed with plenty of data from news sources, cellphones, laptops, workplaces, and so on. Data conveys with tons of information from different data variables like date, string, numeric, and geographical format. How t…

(轉)結婚那天,媽問我:坐在角落里象兩個要飯模樣的人是誰?

人人看到的文章 很感人~~~~結婚那天&#xff0c;媽問我&#xff1a;坐在角落里象兩個要飯模樣的人是誰&#xff1f; 我看過去的時候&#xff0c;有個老頭正盯著我&#xff0c;旁邊還有個老太太&#xff0c;發現我看著他們時趕忙低下頭。我不認識他們但也不象要飯的&#xff0c;…

nginx-1.13.x源碼安裝

Nginx 安裝配置【依賴庫】[ zlib ]&#xff08;下載&#xff09;http://download.chinaunix.net/download.php?id24013&ResourceID12241 [ pcre ]apt-get install libpcre-dev[ openssl ]&#xff08;下載&#xff09;http://download.chinaunix.net/download.php?id3937…

小技巧!CSS 整塊文本溢出省略特性探究

大家好&#xff0c;我是若川。歡迎加我微信 ruochuan12&#xff0c;長期交流學習。今天的文章很有意思&#xff0c;講一講整塊文本溢出省略打點的一些有意思的細節。點擊下方卡片關注我&#xff0c;或者查看源碼系列文章。文本超長打點我們都知道&#xff0c;到今天&#xff08…