2012-01-03 43 views
3

我剛注意到一些奇怪的東西。我認爲,作爲PHP手冊說,session_start()必須之前的任何輸出發送到瀏覽器調用:session_start()在發送輸出後工作

要使用基於cookie的會話,在session_start()必須outputing任何內容到瀏覽器之前被調用。

所以,只是爲了好奇,我創建了兩個腳本。一個是write.php

<?php 
echo 'foo'; 

session_start(); 
$_SESSION['bar'] = 'baz'; 
?> 

而另一種是read.php

<?php 
echo 'foo'; 

session_start(); 
var_dump($_SESSION['bar']); 
?> 

令人奇怪的是,在會話寫入和讀取echo荷蘭國際集團即使經過。

但是,如果我的echo年代後添加一個調用flush(),Apache的錯誤日誌報告:

[星期二年1月3 11點57分21秒2012] [錯誤] [客戶端127.0.0.1] PHP警告:session_start():無法發送會話緩存限制器 - 已在第5行的/var/www/sessions/write.php中發送的頭文件 [Tue Jan 03 03:57:21 2012] [error] [client 127.0.0.1] PHP Stack trace: [Tue Jan 03 11:57:21 2012] [error] [client 127.0.0.1] PHP 1. {main}()/var/www/sessions/write.php: [Tue Jan 03 11:57:21 2012] [error] [client 127.0.0.1] PHP 2. session_start()/var/www/sessions/write.php:5

所以,我的問題是:爲什麼會話在echo之後正確寫入東西?它不是立即發送到瀏覽器嗎?而且,如果是這樣,是否意味着我可以在任何地方開始會議,只要我之前不打電話給flush()

+5

[谷歌「PHP輸出緩衝」](http://www.google.com/search?q=php+output+buffering) – DaveRandom 2012-01-03 11:02:39

回答

6

要使用基於cookie的會話,必須在 向瀏覽器輸出任何內容之前調用session_start()。

這是真的。服務器端cookie設置(與JavaScript cookie設置不同)通過發送HTTP頭來工作。 HTTP標題在實際文檔之前:一旦開始發送文檔,就沒有地方可以使用其他標題。

在你的情況,什麼情況是,這條線:

echo 'foo'; 

...實際上並沒有發送輸出到瀏覽器。相反,它會將一些輸出添加到將在稍後發送的隊列中。 PHP解釋器配置爲保存此輸出,直到發生某些事件(可能腳本結束或隊列達到特定大小)。

output_buffering指令是可能的嫌疑人。

+0

'''output_buffering'''設置爲'''4096'''和'''implicit_flush'''是'''Off'''。所以,讓我的腳本不工作了,甚至無需調用'''的flush()''',我應該使'''implicit_flush'''並設置'''output_buffering'''來'''0 ''',對吧? – 2012-01-03 11:14:58

0

session_start()中的這個錯誤並不意味着你還沒有任何公開的會話。此方法試圖創建新的會話ID,但您已經可以擁有一個。在運行這些腳本之前嘗試刪除所有Cookie。

+0

我做到了。我刪除了'''PHPSESSID''',然後再次運行這些腳本,發生同樣的事情:如果我在''echo''後面加入'''flush()''',** read.php **顯示** NULL **,如果我不顯示,則按預期顯示** baz **。 – 2012-01-03 11:10:35

+0

您必須outbut在PHP設置中啓用緩衝 – kaz 2012-01-03 11:13:24

相關問題