PHP 输出缓冲区“千年”错误?

Posted

技术标签:

【中文标题】PHP 输出缓冲区“千年”错误?【英文标题】:PHP Output Buffer "Millenium" Bug? 【发布时间】:2012-12-22 15:23:04 【问题描述】:

我今天遇到了一个奇怪的问题。

几个月来,我在 php 中使用缓冲区刷新将小字符串大小发送到客户端没有问题。

今天我回到项目,结果发现我的服务器不会发送小于 512 字节的字符串。

这是我的代码:

<?php
    echo "length:".$myUpcomingStringSize;
    ob_flush();
    flush();

    sleep(1);

    for($i = 0; $i < count($allLines); $++) 
        echo $allLines[$i];
        ob_flush();
        flush();
    
?>

这个代码在去年全年都像魅力一样工作。而现在它不再。我玩了一下并添加了一些随机字符。当字符串大小等于或大于 512 时,服务器会发送缓冲区内容。

谁能想象我必须在这里解决的问题?还有其他人面临这个问题吗?或者确实 有人知道如何配置这个最小数据包大小吗?

【问题讨论】:

你试过不同的客户端吗? 那种。我一直使用同一个客户端。但实际上我是在 Objective-C 中编程,所以我在没有侧缓存或类似的东西的情况下获取原始数据 ios 网络堆栈很可能有缓冲。您应该确保您的行以换行符结尾 (\n) 感谢换行提示。虽然没有帮助:( 奇怪的是服务器的行为突然改变了。到现在为止我都没有问题…… 【参考方案1】:

如果您既未更改程序也未更改服务器,则应假定该程序从未按预期工作。众所周知,Windows 系统会缓冲输出,直到输出缓冲区中有一定数量的字节。此缓冲处于系统级别,因此不受任何 PHP 配置的影响。

如果您知道 512 字节是输出缓冲区发送所需的最小值,那么您可以使用类似

define('MIN_OUTPUT_LENGTH', 512);
echo str_pad("length: $myUpcomingStringSize", MIN_OUTPUT_LENGTH, "\0"), '\n';
// (If you run into trouble with the null-bytes, use space character instead)

注意事项

如果您不使用“用户空间”输出缓冲,则ob_flush(); 是多余的。 如果您的for 循环中没有延迟,那么在行间刷新不是一个好主意。特别是对于网络尝试将尽可能多的数据打包到单个数据包中的移动应用程序。 for 循环标头中存在语法错误(表达式$++ 缺少变量标识符,可能是i

【讨论】:

感谢您的回复!我不在 Windows 系统上工作……但我认为你是对的。它可能是偶然起作用的 :) $++ 只是一个错字,我想你也有一个错字:), '\n'str_pad() 正是我想要的,谢谢! @Julian 没有错字(除非我错过了另一个),您可以在 echo 语句中用逗号分隔字符串,例如 echo "a", "b", "c"; 这是有效的 PHP ;) 真的吗?!哈哈,我没注意到 :) 另一个问题:你说循环冲洗不是一个好主意。我这样做是为了增加发送给客户的包裹数量,以便更准确地衡量进度。为什么这不是一个好主意? 在您在问题中编写的代码中,行之间没有真正的延迟,您所做的只是回显一个字符串数组,这几乎是即时的。但是,如果您在两者之间刷新(并且它实际上被发送),您最终可能会获得更差的性能。如果你真的真的必须影响输出缓冲区并且没有办法,你应该只影响输出缓冲区。 (就像在echo $some; flush(); sleep(1) 中一样,除非您希望客户端等待$some

以上是关于PHP 输出缓冲区“千年”错误?的主要内容,如果未能解决你的问题,请参考以下文章

解析PHP中ob_start()函数的用法

PHP基础之输出缓冲区基本概念原理分析

php缓冲区 一些笔记

PHP输出缓冲

PHP基础教程 PHP的页面缓冲处理机制

php输出控制函数和输出函数生成静态页面