當前位置:首頁 » 編程語言 » php輸出緩沖

php輸出緩沖

發布時間: 2023-05-24 15:27:21

⑴ 高質量php代碼的50個技巧(3)

42

43

44

45

/**

Method to execute a command in the terminal

Uses :

1. system

2. passthru

3. exec

4. shell_exec

*/

function terminal($command)

{

//system

if(function_exists('system'))

{

ob_start();

system($command , $return_var);

$output = ob_get_contents();

ob_end_clean();

}

//passthru

else if(function_exists('passthru'))

{

ob_start();

passthru($command , $return_var);

$output = ob_get_contents();

ob_end_clean();

}

//exec

else if(function_exists('基悔exec'))

{

exec($command , $output , $return_var);

$output = implode(" " , $output);

}

//shell_exec

else if(function_exists('shell_exec'))

{

$output = shell_exec($command) ;

}

else

{

$output = 'Command execution not possible on this system';

$return_var = 1;

}

return array('output' => $output , 'status' => $return_var);

}

terminal('ls');

上面的函數將運行shell命令, 只要有一個系統函數可用, 這保持了代碼的一致性.

5. 靈活編寫函數

?

1

2

3

4

5

6

function add_to_cart($item_id , $qty)

{

$_SESSION['cart']['item_id'] = $qty;

}

add_to_cart( 'IPHONE3' , 2 );

使用上面的函數添加單個項目. 而當添加項列表的時候,你要創建另一個函數嗎? 不用, 只要稍加留意不同類型的參數, 就寬好會更靈活. 如:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

慎鋒鉛14

15

16

function add_to_cart($item_id , $qty)

{

if(!is_array($item_id))

{

$_SESSION['cart']['item_id'] = $qty;

}

else

{

foreach($item_id as $i_id => $qty)

{

$_SESSION['cart']['i_id'] = $qty;

}

}

}

add_to_cart( 'IPHONE3' , 2 );

add_to_cart( array('IPHONE3' => 2 , 'IPAD' => 5) );

現在, 同個函數可以處理不同類型的輸入參數了. 可以參照上面的例子重構你的多處代碼, 使其更智能.

6. 有意忽略php關閉標簽

我很想知道為什麼這么多關於php建議的博客文章都沒提到這點.

?

1

2

3

<?php

echo "Hello";

//Now dont close this tag

這將節約你很多時間. 我們舉個例子:

一個 super_class.php 文件

?

1

2

3

4

5

6

7

8

9

<?php

class super_class

{

function super_function()

{

//super code

}

}

?>

//super extra character after the closing tag

index.php

?

1

2

require_once('super_class.php');

//echo an image or pdf , or set the cookies or session data

這樣, 你將會得到一個 Headers already send error. 為什麼? 因為 “super extra character” 已經被輸出了. 現在你得開始調試啦. 這會花費大量時間尋找 super extra 的位置。因此, 養成省略關閉符的習慣:

?

1

2

3

4

5

6

7

8

9

<?php

class super_class

{

function super_function()

{

//super code

}

}

//No closing tag

這會更好.

7. 在某地方收集所有輸入, 一次輸出給瀏覽器

這稱為輸出緩沖, 假如說你已在不同的函數輸出內容:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

function print_header()

{

echo "<p id='header'>Site Log and Login links</p>";

}

function print_footer()

{

echo "<p id='footer'>Site was made by me</p>";

}

print_header();

for($i = 0 ; $i < 100; $i++)

{

echo "I is : $i ';

}

print_footer();

替代方案, 在某地方集中收集輸出. 你可以存儲在函數的局部變數中, 也可以使用ob_start和ob_end_clean. 如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

function print_header()

{

$o = "<p id='header'>Site Log and Login links</p>";

return $o;

}

function print_footer()

{

$o = "<p id='footer'>Site was made by me</p>";

return $o;

}

echo print_header();

for($i = 0 ; $i < 100; $i++)

{

echo "I is : $i ';

}

echo print_footer();

為什麼需要輸出緩沖:

>>可以在發送給瀏覽器前更改輸出. 如 str_replaces 函數或可能是 preg_replaces 或添加些監控/調試的html內容.

>>輸出給瀏覽器的同時又做php的處理很糟糕. 你應該看到過有些站點的側邊欄或中間出現錯誤信息. 知道為什麼會發生嗎? 因為處理和輸出混合了.

8. 發送正確的mime類型頭信息, 如果輸出非html內容的話.

輸出一些xml.

?

1

2

3

4

5

6

$xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>';

$xml = "<response>

<code>0</code>

</response>";

//Send xml data

echo $xml;

工作得不錯. 但需要一些改進.

?

1

2

3

4

5

6

7

$xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>';

$xml = "<response>

<code>0</code>

⑵ 求教php 緩沖區問題

首先你找到php 的配置文件php.ini
1.php.ini中的output_buffering配置
Off: 表示關閉PHP輸出緩存
On: 打開無限大的輸出緩存
4096: 打開大小為4096Byte的輸出緩存

2.php.ini中的implicit_flush配置
On: 表示每次輸出(如echo,print)後自動調用flush()函數後,直接輸出
Off: 與On相反,每次輸出後不會調用flush(),需要等到server buffering滿了才會輸出,但是我們可以用flush()函數代替它,不開啟也沒關系,反而更加靈活

3.ob_flush()函數: 取出PHP buffering中的數據,放入server buffering
4.flush()函數: 取出Server buffering的數據,放入browser buffering
5.ob_start()函數:對於這個函數我現在了解的不是很清楚,因為開啟後輸出就會不受ob_flush()控制,即使使用ob_flush()和flush(),數據也不能立即輸出在瀏覽器上.現在知道的是,如果output_buffering=Off,即使使用了ob_start(),也是無法將輸出數據緩存的,而如果output_buffering=On的話,即使不用ob_start(),輸出數據也可以被PHP緩存,所以覺得ob_start比較廢,暫時不管他
然後我們來看代碼吧(設置output_buffering=4096,implicit_flush=Off)
最後的列印效果是
每隔一秒輸出一個

<html>

<body>

<?php

// ob_start(); //這玩意開了就會不正常,輸出不受ob_flush()控制,不知道到底幹嘛用

// echo str_repeat(' ' ,1000); //IE緩存256Bytes

echo str_repeat(' ' ,1000); //Chrome和FF緩存1000Bytes,這里用來先將瀏覽器緩存用掉,但是很疑惑這一行輸出為什麼沒有被output_buffering存起來,而是直接輸出了

for($i=0;$i<5;$i++) {

echo $i.'<br />';

ob_flush();

flush();

sleep(1);

}

?>

</body>

</html>

至於你的可以這么寫
<?php

echo str_repeat(' ' ,1000);
echo 'a<br/>';

ob_flush();

flush();

sleep(3);
echo 'b<br/>';

?>

⑶ php函數可以沒有輸入和輸出

1、PHP是怎麼進行輸入輸出的
php://stdin, php://stdout 和 php://stderrphp://stdin,php://stdout 和 php://stderr允許訪問 PHP 進程相應的輸入或者輸出流。php://inputphp://input 是個可以訪問請求的原始數據的只讀流。 POST 請求的情況下,最好使用 php://input 來代替 $HTTP_RAW_POST_DATA(原生的post數據),因為它不依賴於特定的 php.ini 指令,內存消耗更少。如下例:結果:php://outputphp://output 是一個只寫的數據流, 允許你以 print 和 echo 一樣的方式 寫入到輸出緩沖區。php://fdphp://fd 允許直接訪問指定的文件描述符。 例如 php://fd/3 引用了文件描述符 3。php://memory 和 php://tempphp://memory 和 php://temp 是一個類似文件 包裝器的數據流,允許讀寫臨時數據。 兩者的唯一區別是 php://memory 總是把數據儲存在內存中, 而 php://temp 會在內存量達到預定義的限制後(默認是 2MB)存入臨時文件中。

臨時文件位置的決定和 sys_get_temp_dir() 的方式一致。php://filterphp://filter 是一種元封裝器, 設計用於數據流打開時的篩選過濾應用。 這對於一體式(all-in-one)的文件函數非常有用,類似 readfile()、 file() 和 file_get_contents(), 在數據流內容讀取之前沒有機會應用其他過濾器。參數如下:如下例:

2、php用 if語句如何輸出資料庫內容
/*這里有個小錯誤:limit是確定從資料庫中讀取記錄的個數,為提高效率,一般不建議這么寫sql語句,因為你目前無法確定游標的位置,它可以在第一條記錄上,也可能在最後一條記錄上,更可能在記錄列表的任意位置

當然我理解你的用意,你是為了測試對資料庫的讀取操作,意思是只要隨意讀扮世取一條記錄就行了

但長期這么下去,你會養成一種不良的習慣,代碼不按標准去寫,也就不可能見到你想要的結果

正確的寫法是:limit[start,lenth] 例如:limit 0,1 意思是讀取第一條記錄

start代表起始位置,lenth代表讀取記錄個數(或者叫步長)就是讀取一次記錄下一次將要移動的指針位置

同時,強烈建議結合where子條件加以判斷後進行讀取。

*/if (mysql_num_rows($rs)>0){echo $rs["name"];//這里是一個致命錯誤,你是輸出不了任何數據的,因為當代碼運行到這時原時候//$rs僅僅戚核是一個mysql_query的操作句柄,更不是一個結果數組

//你用$rs["name"]去引用輸出一個不存在的數組對象高缺掘,會導致php解釋錯誤

}?>

下面是正確的寫法:

0){$row=mysql_fetch_array($rs);

echo $row["name"];}?>

⑷ 實時生成並下載大數據量的EXCEL文件,用PHP如何實現

對於任何一個網站肯定是少不了下載功能,常見的下載功能有圖片、視頻、Excel表格,如果文件比較小的話,那麼不會遇到任何的問題,但是當文件信息而超明銀過了PHP的最大內存,那麼在這個時候它就會有的內存溢出的問題。

那麼它們是因為什麼而發生的?對於這個過程的原理才是埋碧我們應該真正要去弄明白的事情

下載大數據量的EXCEL文件為何要報錯?

PHP在下載大Excel表格的時候,那麼首先它是需要去把MySQL的數據從硬碟上面讀取到內存,但讀取它是一次性載入到我們的內存,如果說它一次性載入的數據量遠遠大於最大內存,然後再來執行瀏覽器的業務下載。那麼這個時候它就會發生我們這個內存溢出。

就比如:說我們現在有100M的數據量,但是我們PHP內存最大隻有64M,那麼這個它肯定是裝不了的,我們可以把那個內存比喻為一個水杯,這個水杯的容量比喻為內存,現在杯子最大容量為64L。你要存放100L。肯定放不下

大事化小,小事化了。拆分成段

從上面可以看到文件下載,它是分為兩步,首先是載入內存然後執行瀏覽器的輸出下載,那麼既然大型文件一次性載入不了,那可以採用「大事化小,小事化了」思路,我們可以實現邊寫邊下載,也激液宴就是分批次的讀取與寫入。

因為用戶的話,只要最終拿到這個文件就可以,對於瀏覽器的下載原理不需要關心。只需要給到文件下載提示給用戶即可,然後後端在實時的分批次的寫入到要下載的文件當中。

實現思路步驟:

1、一設置瀏覽器下載Excel需要的Header

2、打開php://output流,並設置寫入文件句柄。

註:(php://output,是一個可寫的輸出流,允許程序像操作文件一樣將輸出寫入到輸出流中,PHP會把輸出流中的內容發送給web伺服器並返回給發起請求的瀏覽器)

3、獲取資料庫所有數據量,並設置每次查詢的條數,通過這兩個值計算分批查詢的次數

4、基於分批查詢的次數循環查詢資料庫,然後寫入到文件中,同時清除本次操作變數內存,刷新緩沖到瀏覽器,讓瀏覽器的文件始終實時保持到最新的大小

註:刷新用ob_flush、flush()

PHP的I/O流

在這里我們用到了PHP的一個IO的輸入輸出,也就是我們常用的

php://inputphp://output。

php://input

php://input可以讀取原始的POST數據。相較於$form-data」.

註:p>

php://output是一個只寫的數據流,允許你以print和echo一樣的方式寫入到輸出緩沖區。

綜上:實現思維與原理很重要如有感悟,歡迎在線咨詢

⑸ PHP里的output_buffering 怎麼開啟

在PHP.INI可以設置以下與輸出緩沖有關的:
名稱 默認值 作用范圍 修正記錄
output_buffering "0" PHP_INI_PERDIR
output_handler NULL PHP_INI_PERDIR 自 PHP 4.0.4 起可用
implicit_flush "0" PHP_INI_ALL 在 PHP <= 4.2.3 版本中是 PHP_INI_PERDIR

簡單解釋如下:
output_buffering boolean/integer
該選項設置為 On 時,將在所有的腳本中使用輸出控制。如果要限制輸出緩沖區的最大值,可將該選項設定為指定的最大位元組數(例如 output_buffering=4096)。從PHP 4.3.5 版開始,該選項在 PHP-CLI 下總是為 Off。

output_handler string
該選項可將腳本所有的輸出,重定向到一個函數。例如,將 output_handler 設置為 mb_output_handler() 時,字元的編碼將被修改為指定的編碼。設置的任何處理函數,將自動的處理輸出緩沖。

注意: 不能同時使用 mb_output_handler() 和 ob_iconv_handler(),也不能同時使用 ob_gzhandler() 和 zlib.output_compression。

注意: 只有內置函數可以使用此指令。對於用戶定義的函數,使用 ob_start()。

implicit_flush boolean
默認為 FALSE。如將該選項改為 TRUE,PHP 將使輸出層,在每段信息塊輸出後,自動刷新。這等同於在每次使用 print()、echo() 等函數或每個 HTML 塊之後,調用 PHP 中的 flush() 函數。

不在web環境中使用 PHP 時,打開這個選項對程序執行的性能有嚴重的影響,通常只推薦在調試時使用。在 CLI SAPI 的執行模式下,該標記默認為 TRUE。

參見 ob_implicit_flush()。

設置了肯定會有用的,除非你修改的PHP.INI位置不是系統使用的那個,比如一般是C::\WINDOWS\PHP.INI,當然可以設置到其它地方。另外控制台程序是不緩沖的。

另外,你還可以在程序裡面控制輸出緩沖,請參考手冊裡面的「CXIV. Output Control 輸出控制函數」那一章,主要有如下函數:

flush -- 刷新輸出緩沖
ob_clean -- Clean (erase) the output buffer
ob_end_clean -- Clean (erase) the output buffer and turn off output buffering
ob_end_flush -- Flush (send) the output buffer and turn off output buffering
ob_flush -- Flush (send) the output buffer
ob_get_clean -- Get current buffer contents and delete current output buffer
ob_get_contents -- Return the contents of the output buffer
ob_get_flush -- Flush the output buffer, return it as a string and turn off output buffering
ob_get_length -- Return the length of the output buffer
ob_get_level -- Return the nesting level of the output buffering mechanism
ob_get_status -- Get status of output buffers
ob_gzhandler -- ob_start callback function to gzip output buffer
ob_implicit_flush -- Turn implicit flush on/off
ob_list_handlers -- List all output handlers in use
ob_start -- Turn on output buffering
output_add_rewrite_var -- Add URL rewriter values
output_reset_rewrite_vars -- Reset URL rewriter values

例子程序:

<?php

ob_start();
echo "Hello\n";

setcookie("cookiename", "cookiedata");

ob_end_flush();

?>

⑹ PHP應用中常用的9大緩存技術

一、全頁面靜態化緩存



也就是將頁面全部生成html靜態頁面,用戶訪問時直接訪問的靜態頁面,而不會去走php伺服器解析的流程。此種方式,在CMS系統中比較常見,比如dedecms;


一種比較常用的實現方式是用輸出緩存:


Ob_start()******要運行的代碼*******$content=Ob_get_contents();****將緩存內容寫入html文件*****Ob_end_clean();


二、數據緩存


顧名思義,就是緩存數據的一種方式;比如,商城中的某個商品信息,當用商品id去請求時,就會得出包括店鋪信息、商品信息等數據,此時就可以將這些數據緩存到一個php文件中,文件名包含商品id來建一個唯一標示;下一次有人想查看這個商品時,首先就直接調這個文件裡面的信息,而森塌不用再去資料庫查詢;其實緩存文件中緩存的就是一個php數組之類;


Ecmall商城系統裡面就用了這種方式;




三、查詢緩存


其實這跟數據緩存是一個思路,就是根據查詢語句來緩存;將查詢得到的數據緩存在一個文件中,下次遇到相同的查詢時,就直接先從這個文件裡面調數據,不會再去查資料庫;但此處的緩存文件名可能就需要以查詢語句為基點來建立唯一標示;


按時間變更進行緩存


就是對於緩存文件您需要設一個有效時間,在這個有效時間內,相同的訪問才會先取緩存文件的內容,但是超過設定的緩存時間,就需要重新從資料庫中獲取數據,並生產最新的緩存文件;比如,我將我們商城的首頁就是設置2個小時更新一次。


四、頁面部分緩存


該種方式,是將一個頁面中不經常變的部分進行靜態緩存,而經常變化的塊不緩存,最後組裝在一起顯示;可此哪圓以使用類似於ob_get_contents的方式實現,也可以利用類似ESI之類的頁面片段緩存策略,使其用來做動態頁面中相對靜態的片段部分的緩存。


該種方式可以用於如商城中的商品頁;


五、Opcode緩存


首先php代碼被解析為Tokens,然後再編譯為Opcode碼,最後執行Opcode碼,返回結果;所以,對於相同的php文件,第一次運行時可以緩存其Opcode碼,下次再執行這個頁面時,直接會去找到緩存下的opcode碼,直接執行最後一步,而不再需要中間的步驟了。


比較知名的是XCache、TurckMMCache、PHPAccelerator等。


六、按內容變更進行緩存


這個也並非獨立的緩存技術,需結合著用;就是當資料庫內容被修改時,即刻更新緩存文件;


比如,一個人流量很大的商城,商品很多,商品表必然比較大,這表的壓力也比較重;我們就可以對商品顯示頁進行頁面緩存;


當商家在後台修改這個商品的信息時,點擊保存,我們同時就更新緩存文件;那麼,買家訪問這個商品信息時,實際問的是一個靜態頁面,而不需要再去訪問資料庫;


試想,如果對商品頁不緩存,那麼每次訪問一個商品就要去資料庫查一次,如果有10萬人在線瀏覽商品,那伺服器壓力就大了;


七、內存式緩存


提到這個,可能大家想到的首先就是Memcached;memcached是高性能的分布式內存緩存伺服器。一般的使用目的是,通過緩存資料庫查詢結果,減少資料庫訪問次數,以提高動態緩孝Web應用的速度、提高可擴展性。


它就是將需要緩存的信息,緩存到系統內存中,需要獲取信息時,直接到內存中取;比較常用的方式就是key_>value方式;


connect($memcachehost,$memcacheport)ordie("Couldnotconnect");$memcache->set('key','緩存的內容');$get=$memcache->get($key);//獲取信息?>


八、apache緩存模塊


apache安裝完以後,是不允許被cache的。天通苑IT培訓認為如果外接了cache或squid伺服器要求進行web加速的話,就需要在htttpd.conf里進行設置,當然前提是在安裝apache的時候要激活mod_cache的模塊。


⑺ php echo 形式輸出的圖片怎樣讓瀏覽器緩存(緩存相關的http頭已經試過了,無效,每次都是200),謝謝

Output Control 函數可以讓你自由控制腳本中數據的輸出。它非常地有用,特別是對於:當你想在數據已經輸出後,再輸出文件頭的情況。
輸出控制函數不對使用 header() 或 setcookie(), 發送的文件頭信息產生影響,只對那些類似於 echo() 和 PHP 代碼的數據塊有作用。
我們先舉一個簡單的例子,讓大家對Output Control有一個大致的印象:
Example 1.
復制代碼 代碼如下:
<?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.
復制代碼 代碼如下:
<?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()函數的輸出怎麼辦呢?在沒有緩沖區控制之前,可以說一點辦法也沒有,但是有了緩沖區的控制,我們可以輕松的解決:
復制代碼 代碼如下:
<?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.
<?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.
<?
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 <[email protected]>
** 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 protected]>
** 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 protected])
** 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以上的頁面,會產生效果,而且頁面越大,效果越明顯……

⑻ 用php語言從伺服器返回數據超過80k後速度就非常非常慢!測試後發現好像是輸出緩存問題,請問怎麼解決!

對於php的輸出,貌似apache採取的策略是小段輸出直接傳輸,大段輸出就切割成chunked分段。在chunked分段沒有傳輸完成之前,apache和php一直保持連接狀態。也就是說,如果php的輸出字元串比較小,那麼apache會把這些數據暫存,等到php執行完了之後再發給瀏覽器。而當php輸出大段字元的時候,apache就不會緩存輸出,直接把輸出丟給瀏覽器,而且在此過程中會暫時停止php的執行!
所以使用緩存是解決此類問題的根本辦法。ob_start()就是啟用php的緩沖區。php還可以通過安裝xcache等緩存模塊實現。apache中開啟gzip壓縮也可以。

⑼ PHP嵌套輸出緩沖怎麼寫

手冊說明如下:
ob_get_level() will always return 0 inside a destructor.
This happens because the garbage collection for output buffers has already done before the destructor is called

想要正確輸出也很簡單:

ob_end_clean();
echo ob_get_level(); //0

回到正題:

ob_end_clean();

ob_start();
echo 'php1';//此處並不會在頁面中輸出
$a = ob_get_level();
$b = ob_get_contents();//獲得緩存結果,賦予變數
ob_clean();

ob_start();
echo 'php2';//此處並不會在頁面中輸出
$c = ob_get_level();
$d = ob_get_contents();//獲得緩存結果,賦予變數
ob_clean();

ob_start();
echo 'php3';//此處並不會在頁面中輸出
$e = ob_get_level();
$f = ob_get_contents();//獲得緩存結果,賦予變數
ob_clean();

echo 'level:'.$a.',ouput:'.$b.'嫌毀<br>';
echo 'level:'.$c.',ouput:'.$d.'<br>'悄神;
echo 'level:'.$e.',ouput:'芹運備.$f.'<br>';

結果如下:
level:1,ouput:php1
level:2,ouput:php2
level:3,ouput:php3

當然,當你關閉某個級別的緩沖,如下測試:

ob_end_clean();

ob_start();
echo 'php1';
$a = ob_get_level();
$b = ob_get_contents();
ob_clean();

ob_start();
echo 'php2';
$c = ob_get_level();
$d = ob_get_contents();
ob_end_clean(); //清空緩存並關閉緩存

ob_start();
echo 'php3';
$e = ob_get_level();
$f = ob_get_contents();
ob_clean();

echo 'level:'.$a.',ouput:'.$b.'<br>';
echo 'level:'.$c.',ouput:'.$d.'<br>';
echo 'level:'.$e.',ouput:'.$f.'<br>';

結果如下:
level:1,ouput:php1
level:2,ouput:php2
level:2,ouput:php3

⑽ php 緩沖問題

當程序執行完了,就要輸出的。
ob_start(); 的作用只是不讓程序邊執行邊輸出,而是保存到緩沖區當用到flush()或ob_end_flush()的時候輸出。
而當程序執行完了之後,所有的緩沖都會被輸出。所以,即便是你沒調用那兩個函數,也要輸出。
注意一個概念:「邊執行邊輸出」!
PHP預設情況下是邊執行邊輸出的,也就是說程序執行到有echo、print之類的語句的地方,就輸出了。

熱點內容
ct4哪個配置性價比最高 發布:2025-05-19 15:38:02 瀏覽:952
如何設置強緩存的失效時間 發布:2025-05-19 15:21:28 瀏覽:695
winxp無法訪問 發布:2025-05-19 15:19:48 瀏覽:947
文件預編譯 發布:2025-05-19 15:14:04 瀏覽:643
怎麼在伺服器上掛公網 發布:2025-05-19 15:14:02 瀏覽:272
濟南平安e通如何找回密碼 發布:2025-05-19 14:56:58 瀏覽:176
安卓手機如何找到iccid碼 發布:2025-05-19 14:46:51 瀏覽:227
編譯的內核為什麼那麼大 發布:2025-05-19 14:45:21 瀏覽:179
什麼控制壓縮 發布:2025-05-19 14:28:13 瀏覽:931
網路伺服器忙指什麼 發布:2025-05-19 14:28:10 瀏覽:189