天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

php緩沖 output_buffering的使用詳解

buffer
buffer是一個內存地址空間,Linux系統默認大小一般為4096(4kb),即一個內存頁。主要用于存儲速度不同步的設備或者優先級不同的設備之間傳辦理數據的區域。通過buffer,可以使進程這間的相互等待變少。這里說一個通俗一點的例子,你打開文本編輯器編輯一個文件的時候,你每輸入一個字符,操作系統并不會立即把這個字符直接寫入到磁盤,而是先寫入到buffer,當寫滿了一個buffer的時候,才會把buffer中的數據寫入磁盤,當然當調用內核函數flush()的時候,強制要求把buffer中的臟數據寫回磁盤。

同樣的道理,當執行echo,print的時候,輸出并沒有立即通過tcp傳給客戶端瀏覽器顯示, 而是將數據寫入php buffer。php output_buffering機制,意味在tcp buffer之前,建立了一新的隊列,數據必須經過該隊列。當一個php buffer寫滿的時候,腳本進程會將php buffer中的輸出數據交給系統內核交由tcp傳給瀏覽器顯示。所以,數據會依次寫到這幾個地方:echo/print -> php buffer -> tcp buffer -> browser

php output_buffering
默認情況下,php buffer是開啟的,而且該buffer默認值是4096,即4kb。你可以通過在php.ini配置文件中找到output_buffering配置.當echo,print等輸出用戶數據的時候,輸出數據都會寫入到php output_buffering中,直到output_buffering寫滿,會將這些數據通過tcp傳送給瀏覽器顯示。你也可以通過ob_start()手動激活php output_buffering機制,使得即便輸出超過了4kb數據,也不真的把數據交給tcp傳給瀏覽器,因為ob_start()將php buffer空間設置到了足夠大。只有直到腳本結束,或者調用ob_end_flush函數,才會把數據發送給客戶端瀏覽器。

1.當output_buffering=4096,并且輸出較少數據(少于一個buffer)
復制代碼 代碼如下:
<?php
for ($i = 0; $i < 10; $i++) {
echo $i . '<br/>';
sleep($i + 1); //
}
?>

現象:不是每隔幾秒就會有間斷性輸出,而是直到響應結束,才能看一次性看到輸出,在等待服務器腳本處理結束之前,瀏覽器界面一直保持空白。這是因為,數據量太小,php output_buffering沒有寫滿。寫數據的順序,依次是echo->php buffer->tcp buffer->browser

2.當output_buffering=0,并且輸出較少數據(少于一個buffer)
復制代碼 代碼如下:
<?php
//通過ini_set('output_buffering', 0)并不生效
//應該編輯/etc/php.ini,設置output_buffering=0禁用output buffering機制
//ini_set('output_buffering', 0); //徹底禁用output buffering功能
for ($i = 0; $i < 10; $i++) {
echo $i . '<br/>';
flush(); //通知操作系統底層,盡快把數據給客戶端瀏覽器
sleep($i + 1); //
}
?>

現象:與剛才顯示并不一致,禁用了php buffering機制之后,在瀏覽器可以斷斷續續看到間斷性輸出,不必等到腳本執行完畢才看到輸出。這是因為,數據沒有在php output_buffering中停留。寫數據的順序依次是echo->tcp buffer->browser

3.當output_buffering=4096.,輸出數據大于一個buffer,不調用ob_start()
復制代碼 代碼如下:
#//創建一個4kb大小的文件
$dd if=/dev/zero of=f4096 bs=4096 count=1
<?php
for ($i = 0; $i < 10; $i++) {
echo file_get_contents('./f4096') . $i . '<br/>';
sleep($i +1);
}
?>

現象:響應還沒結束(http連接沒有關閉),斷斷續續可以看到間斷性輸出,瀏覽器界面不會一直保持空白。盡管啟用了php output_buffering機制,但依然會間斷性輸出,而不是一次性輸出,是因為output_buffering空間不夠用。每寫滿一個php buffering,數據就會發送到客戶端瀏覽器。

4.當output_buffering=4096, 輸出數據大于一個tcp buffer, 調用ob_start()
復制代碼 代碼如下:
<?php
ob_start(); //開啟php buffer
for ($i = 0; $i < 10; $i++) {
echo file_get_contents('./f4096') . $i . '<br/>';
sleep($i + 1);
}
ob_end_flush();
?>

現象:直到服務端腳本處理完成,響應結束,才看到完整輸,輸出間隔時間很短,以至你感受不到停頓。在輸出之前,瀏覽器一直保持著空白界面,等待服務端數據。這是因為,php一旦調用了ob_start()函數,它會將php buffer擴展到足夠大,直到ob_end_flush函數調用或者腳本運行結速才發送php buffer中的數據到客戶端瀏覽器。

output buffering函數

1.ob_get_level
返回輸出緩沖機制的嵌套級別,可以防止模板重復嵌套自己。

1.ob_start
激活output_buffering機制。一旦激活,腳本輸出不再直接出給瀏覽器,而是先暫時寫入php buffer內存區域。

php默認開啟output_buffering機制,只不過,通過調用ob_start()函數據output_buffering值擴展到足夠大。也可以指定$chunk_size來指定output_buffering的值。$chunk_size默認值是0,表示直到腳本運行結束,php buffer中的數據才會發送到瀏覽器。如果你設置了$chunk_size的大小,則表示只要buffer中數據長度達到了該值,就會將buffer中的數據發送給瀏覽器。

當然,你可以通過指定$ouput_callback,來處理buffer中的數據。比如函數ob_gzhandler,將buffer中的數據壓縮后再傳送給瀏覽器。

2.ob_get_contents
獲取一份php buffer中的數據拷貝。值得注意的是,你應該在ob_end_clean()函數調用之前調用該函數,否則ob_get_contents()返回一個空字符中。

3.ob_end_flush與ob_end_clean
這二個函數有點相似,都會關閉ouptu_buffering機制。但不同的是,ob_end_flush只是把php buffer中的數據沖(flush/send)到客戶端瀏覽器,而ob_clean_clean將php bufeer中的數據清空(erase),但不發送給客戶端瀏覽器。ob_end_flush調用之后,php buffer中的數據依然存在,ob_get_contents()依然可以獲取php buffer中的數據拷貝。而ob_end_clean()調用之后ob_get_contents()取到的是空字符串,同時瀏覽器也接收不到輸出,即沒有任何輸出。

慣用案例
常常在一些模板引擎和頁面文件緩存中看到ob_start()使用。下面濕CI中加載模板的程序代碼:
復制代碼 代碼如下:
<SPAN style="WHITE-SPACE: pre">  </SPAN>/*
   * Buffer the output
   *
   * We buffer the output for two reasons:
   * 1. Speed. You get a significant speed boost.
   * 2. So that the final rendered template can be
   * post-processed by the output class.  Why do we
   * need post processing?  For one thing, in order to
   * show the elapsed page load time.  Unless we
   * can intercept the content right before it's sent to
   * the browser and then stop the timer it won't be accurate.
   */
  ob_start();
  // If the php installation does not support short tags we'll
  // do a little string replacement, changing the short tags
  // to standard php echo statements.
  if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
  {
                        //替換短標記<?=***>
   echo eval('?>'.preg_replace("/;*/s*/?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
  }
  else
  {
   include($_ci_path); // include() vs include_once() allows for multiple views with the same name
  }

                //記錄調試信息
  log_message('debug', 'File loaded: '.$_ci_path);
  // Return the file data if requested
  if ($_ci_return === TRUE)
  {
   $buffer = ob_get_contents();
   @ob_end_clean();
   return $buffer;
  }
  /*
   * Flush the buffer... or buff the flusher?
   *
   * In order to permit views to be nested within
   * other views, we need to flush the content back out whenever
   * we are beyond the first level of output buffering so that
   * it can be seen and included properly by the first included
   * template and any subsequent ones. Oy!
   *
   */
  if (ob_get_level() > $this->_ci_ob_level + 1)
  {
   ob_end_flush();
  }
  else
  {
                        //將模板內容添加到輸出流中
   $_ci_CI->output->append_output(ob_get_contents());
                        //清除buffer
   @ob_end_clean();
  }

php技術php緩沖 output_buffering的使用詳解,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 早乙女由依在线观看 | 国产精品婷婷久青青原 | 美女丝袜夹b | 琪琪色原网20岁以下热热色原网站 | 午夜精品久久久久久影视riav | 亚洲乱码中文字幕久久 | 精品四虎国产在免费观看 | 2021国产精品国产精华 | 青青草在线视频 | aaa在线观看视频高清视频 | 无码一区国产欧美在线资源 | 日本久久网站 | 韩国黄电影 | 饥渴难耐的浪荡艳妇在线观看 | 亚洲午夜精品一区二区公牛电影院 | 亚洲欧洲日产国产 最新 | 色男人综合 | 黄桃AV无码免费一区二区三区 | 欧美激情视频在线观看一区二区三区 | 男女亲吻摸下面吃奶视频 | 国产日韩精品SUV | 国产99视频精品一区 | 大咪咪dvd | 先锋影音av最新资源网 | 中文字幕国产视频 | 久久99精国产一区二区三区四区 | 色情在线avav| 亚洲欧美日韩另类精品一区二区三区 | 亚洲免费精品 | brazzers欧美最新版视频 | 最近的2019中文字幕国语 | 日本一区精品久久久久影院 | 无码射肉在线播放视频 | 日日夜夜国产 | 色婷婷亚洲精品天天综合影院 | 中文字幕久久久 | 韩国精品无码少妇在线观看网站 | 国产日韩在线欧美视频 | 久久国产精品福利影集 | 国产高清在线露脸一区 | 亚洲伊人情人综合网站 |