抑制session_start()警告(已发送标头)

时间:2013-11-01 15:54:31

标签: php session download

我遇到需要多次在文件中间调用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()的每次后续调用都会返回警告,在我的情况下会将警告注入到下载的文件中,是否有任何以编程方式正确的方法来抑制它们?

现在我想到了两个解决方案,但我对其中没有一个感到满意:

  1. 调用@session_start()而不是session_start() - 这不是一种好习惯,因为它会抑制函数返回的所有警告和错误。
  2. 在每次文件写入迭代结束时调用ob_clean()清空输出缓冲区,以删除注入缓冲区的警告以写入文件。 - 在这种情况下,警告仍然存在,我没有正确处理情况,我只是删除警告并忽略它。
  3. 所以我的问题是,如何正确地每个文件正确调用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);
    ?>
    

0 个答案:

没有答案