为什么 php 命令 flush 在 Safari 中不起作用?

Why is the php command flush not working in Safari?

提问人:Sanderadio 提问时间:5/9/2023 最后编辑:E_net4Sanderadio 更新时间:5/10/2023 访问量:108

问:

我有一个耗时的 php 脚本,所以我想给用户一些反馈。简化它以找到核心问题。此脚本在Firefox中运行良好(立即刷新输出),但Safari会等到生成所有内容。为什么?我该如何解决这个问题?

<?php
ini_set('max_execution_time', 0);
header('Content-Encoding: none;'); 
header('Content-type: text/html; charset=utf-8');

$j = 8;
$k = pow(2, 10);

echo "One moment please...".str_pad('', $k)."<br />\n<br />\n";
flush();

$i = 0;
while ($i < $j) { 
    $i++;
    echo "Test ".$i.str_pad('',$k)."<br />\n";
    flush();
    sleep(1);
} 
?>

顺便说一句:Chrome根本不会加载此页面,它给了我.ERR_CONTENT_DECODING_FAILED

此外,我试图把

<IfModule mod_env.c>
    SetEnv no-gzip 1
</IfModule>

在 .htaccess 中,但没有运气。也试过了.如何让Safari(和Chrome)与Firefox一样做任何线索吗?SetEnv no-gzip dont-vary


我阅读了 php.net 上关于 、 、 等的所有内容,我阅读了几乎所有关于 flush 的问题 + 过去 20+ 年对 Stackoverflow 的所有评论。 我试图添加或、添加、、和/或。我在我的之前或之后,试图将值提高到 2^16 (65,536),但没有任何帮助。
不幸的是,我似乎无法控制我的托管服务提供商(使用 FastCGI 运行 PHP 8.1)的 Apache 服务器。既然它在Firefox上工作,我想我一定做对了什么。
flush()ob_flush()ob_start()ini_set('output_buffering', 'On');ini_set('output_buffering', 'Off');ob_start(null, 4096);ini_set('zlib.output_compression', 'Off');header('Cache-Control: no-cache');header('X-Content-Type-Options: nosniff');header('X-Accel-Buffering: no');@ob_flush();flush();str_pad

php google-chrome firefox safari flush

评论


答:

0赞 hareth py 5/9/2023 #1

Edit:
旨在用作 ob_start() 的回调函数,以帮助将 gz 编码的数据发送到支持压缩网页的 Web 浏览器。
ob_start("ob_gzhandler")

<?php
ini_set('max_execution_time', 0);
header('Content-Encoding: none;');
header('Content-type: text/html; charset=utf-8');
ob_start("ob_gzhandler");
$j = 8;
$k = pow(2, 10);

echo "One moment please...".str_pad('', $k)."<br />\n<br />\n";


$i = 0;
while ($i < $j) {
    $i++;
    echo "Test ".$i.str_pad('',$k)."<br />\n";
    ob_flush();
    sleep(1);
}
?>

输出(在 Chrome 上):

请稍等...

测试 1 测试 2 测试 3 测试 4 测试 5 测试 6 测试 7 测试 8

评论

0赞 Sanderadio 5/9/2023
谢谢。我也尝试过,但所有浏览器都这样做:等到生成所有内容(8 秒后)再将其显示给用户。至少它的工作方式与我在Firefox中所希望的那样:在每行之后立即显示每一行。还有什么线索吗?Content-encoding: nonesleep(1);
0赞 hareth py 5/9/2023
找到它!,代码已被编辑。它立即在 chrome 上为我显示,尝试添加 ob_start(“ob_gzhandler”);在一切都会告诉内容之前,内容被压缩 php.net/manual/en/function.ob-gzhandler.php
0赞 hareth py 5/9/2023
请注意,代码执行起来需要一点时间,但希望它能给出预期的结果
0赞 Sanderadio 5/9/2023
我真的很感谢你的想法。但是,添加后,它仍然会一次显示所有内容,而不是每秒生成一行(至少在装有 Safari 16.4、Firefox 113.0 和 Chrome 113.0.5672.92 的 iMac 上)。ob_start("ob_gzhandler");
0赞 hareth py 5/9/2023
您是否也将 flush() 修改为 ob_flush()?
1赞 Sanderadio 5/9/2023 #2

多亏了hareth py,我找到了答案!

<?php 
ini_set('max_execution_time', 0);
header('Content-Encoding: none;');
header('Content-type: text/html; charset=utf-8;');
ob_start("ob_gzhandler");
$j = 200;
$k = pow(2, 10);

echo "One moment please...".str_pad('', $k)."<br />\n<br />\n";


$i = 0;
while ($i < $j) {
    $i++;
    echo "Test ".$i.str_pad('',$k)."<br />\n";
    ob_flush();
    usleep(100000);
} 
?>

我将$j提高到 200,并将睡眠时间降低到 0.1 秒。Safari的响应速度确实有点慢,但它最终会逐行显示。就像 Firefox 和 Chrome 一样。