如何通过多个输出缓冲区和Gzip保持会话的有效性


How do you keep a session alive through multiple output buffers and Gzip?

我最近意识到,我对网站的修改导致会话在页面重新加载之间停止。在做了一点调查后,我注意到PHP.net上session_start()手册中的这一行:

如果用户使用ob_gzhandler或类似的ob_start(),那么函数顺序对于正确的输出非常重要。例如,在启动会话之前,必须注册ob_gzhandler。

问题是,我很早就在页面中调用了session_start()。我想一开始可能会添加Gzip处理程序,但这不起作用,因为我在整个脚本执行过程中打开并清理了几个输出缓冲区(通常每页加载3或4个)。在页面末尾,我通过将所有缓冲区相互插入并填充数据来组合所有缓冲区,然后使用Gzip处理程序打开最终输出缓冲区,并将最终结果返回到页面。现在的问题是:我如何继续通过PHP完成Gzip压缩,并让会话在一旁工作?在打开最终输出缓冲区后,我尝试再次重新打开会话,但没有效果。一开始打开额外的输出缓冲区只会导致浏览器出现内容编码错误。有什么想法吗?

下面是一个非常简化的可视化代码片段。抱歉,我的代码跨越了几页冗长的代码,所以我不能粘贴所有内容。

session_start(); // The session is started early on for data
...
ob_start(); // Start an output buffer
echo "some content here"; // Some stuff is processed and sent
$data = ob_get_clean(); // That data is stored for later
...
ob_start(); // Another output buffer is started
echo "some other stuff"; // Different content for another piece of the page is sent
$moredata = ob_get_clean(); // That data is also stored for later use
...
ob_start(); // Another output buffer
echo $data.$moredata; // The data so far is more or less "combined" into the final template
$final = ob_get_clean(); // All of this is stored for final output
// Some other final touches are made to the final data here
ob_start("ob_gzhandler"); // Start the Gzip handler
echo $final; // Send the final output

使用调用session_start()后获取会话id

$id = session_id();

然后,在代码结束时,使用重建会话

session_id($id);