我遇到需要多次在文件中间调用session_start()
的情况。显然,当session_start()
输出缓冲区时,我收到以下警告:
Warning: session_start(): Cannot send session cookie - headers already sent by...
Warning: session_start(): Cannot send session cache limiter - headers already sent...
StackOverflow上有很多关于由session_start()
引起的与标题相关的警告的内容。在你决定将这篇文章标记为重复之前,请继续阅读 - 你会看到,它是不同的。
其他线程中提出的大多数解决方案建议在创建任何PHP输出之前将session_start()
放在文件的开头。如果session_start()
只需要为每个文件调用一次,这可能是合适的解决方案 - 但是,这不是我的情况。
我有一个文件下载脚本(请参阅下面的代码。)我的脚本会在文件下载期间定期更新带有下载进度状态的'$ _SESSION'变量。然后我通过AJAX请求定期发布另一个脚本,它监视下载进度并通知我的JavaScript代码。
为避免锁定$_SESSION
变量,因此每次下载文件时,我必须多次调用session_start()
和session_write_close()
,这发生在PHP文件的循环中。
随着对session_start()
的每次后续调用都会返回警告,在我的情况下会将警告注入到下载的文件中,是否有任何以编程方式正确的方法来抑制它们?
现在我想到了两个解决方案,但我对其中没有一个感到满意:
@session_start()
而不是session_start()
- 这不是一种好习惯,因为它会抑制函数返回的所有警告和错误。ob_clean()
清空输出缓冲区,以删除注入缓冲区的警告以写入文件。 - 在这种情况下,警告仍然存在,我没有正确处理情况,我只是删除警告并忽略它。所以我的问题是,如何正确地每个文件正确调用session_start()
和session_write_close()
并避免收到警告?
<?php
//...
// file download in small pieces
while(!feof($file_source))
{
$chunk_data = fread($file_source, $chunk_size);
print($chunk_data);
ob_flush();
flush();
$bytes_already_transferred += strlen($chunk_data);
$percent_complete = round(($bytes_already_transferred / $file_size) * 100);
// update session variable, but how to avoid warnings?
if (session_status() == PHP_SESSION_NONE) session_start();
$_SESSION['DownloadProgress'] = $percent_complete;
session_write_close();
usleep(1000);
}
fclose($file_source);
?>