我有一种情况,我需要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()
. 现在,在您决定将此帖子标记为重复之前,请继续阅读 - 您会看到,它是不同的。
其他线程中建议的大多数解决方案都建议session_start()
在进行任何 PHP 输出之前将其放在文件的开头。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);
?>