当前位置: 首页 > 面试题库 >

如何在PHP中禁用输出缓冲

微生令
2023-03-14
问题内容

我编写了一个简单的中继脚本,该脚本连接到网络摄像机并从套接字读取数据,并使用打印功能输出此数据。数据是已设置边界的MJPG数据。我只是输出读取的数据。

问题是PHP似乎正在缓冲这些数据。当我将相机设置为1
FPS时,Feed将冻结7-8秒,然后快速显示8帧。如果将分辨率设置为很大,则相机每秒将以大约1帧的速度移动。我认为那时正在发生一些缓冲(因为大尺寸的缓冲区会很快填充,而小尺寸的缓冲区不会填充),而且我不知道如何禁用此缓冲。有人知道怎么做吗?

码:

ignore_user_abort(false);

$boundary = "myboundary";

//Set this so PHP doesn't timeout during a long stream
set_time_limit(0);

$socketConn = @fsockopen ("192.168.1.6", 1989, $errno, $errstr, 2);
if (!$socketConn)
exit();
stream_set_timeout($socketConn, 10);
fputs ($socketConn, "GET /mjpeg HTTP/1.0\r\n\r\n");

//Setup Header Information
header("Cache-Control: no-cache");
header("Cache-Control: private");
header("Pragma: no-cache");
header("Content-type: multipart/x-mixed-replace; boundary=$boundary");

@ini_set('implicit_flush', 1);
for ($i = 0; $i < ob_get_level(); $i++)
ob_end_flush();
ob_implicit_flush(1);

stream_set_blocking($f2, false);

//Send data to client
while (connection_status() == CONNECTION_NORMAL)
{
    $chunk = fread($socketConn, 128);
    print $chunk;   
}

fclose($socketConn);

问题答案:

tl; dr版本

做两件事:

  1. 禁用用户空间输出缓冲区,或者…

    • 在全球范围内,通过…

    • output_buffering在您的php.ini中关闭,或

    • output_buffering使用以下命令在Apache配置中关闭

                  php_flag "output_buffering" Off
      
    • 或仅针对您关心的脚本,通过以下任一方式…

    • 致电ob_end_flush(),或

    • 呼唤 ob_end_clean()
    • 另外,通过以下任一方法,尽可能禁用服务器级别的输出缓冲区:

    • ob_implicit_flush()在脚本的开头调用,或者

    • flush()在每个echo将输出添加到响应主体的语句或其他语句之后调用

较长的版本

令人困惑的是,可能存在两个相关的缓冲层,PHP文档在区分这两个方面做得很差。

输出缓冲区

PHP文档通常将第一层称为“输出缓冲区”。此缓冲层仅影响到HTTP响应 正文
的输出,而不影响标头。您可以使用打开缓冲输出ob_start()ob_end_flush()或者使用或将其关闭ob_end_clean()。您还可以使用output_bufferingphp.ini中的选项使所有脚本自动从输出缓冲开始。

对于生产版本的php.ini,此选项的默认值为4096,这意味着将在输出缓冲区中缓冲输出的前4096个字节,这时将对其进行刷新并关闭输出缓冲。

您可以通过在php.ini文件中将设置output_bufferingOff(或使用

php_flag "output_buffering" Off

如果您使用的是Apache,请在Apache配置中使用。或者,您可以通过调用ob_end_clean()ob_end_flush()在脚本的开头禁用单个脚本的功能。

写缓冲区和Web服务器缓冲区

PHP手册将输出缓冲区之外的内容称为“写缓冲区”,以及Web服务器具有的任何缓冲系统。如果您通过mod_php和Apache一起使用PHP和Apache
,而没有使用mod_gzip,则可以调用flush()来刷新它们;与其他后端一样,它也可能会起作用,尽管该手册对提供保证不屑一顾:

描述

void flush ( void )

刷新PHP的写缓冲区以及PHP使用的任何后端PHP(CGI,Web服务器等)。这会尝试将当前输出一直推送到浏览器,但有一些警告。

flush()
可能无法覆盖Web服务器的缓冲方案,并且对浏览器中的任何客户端缓冲都没有影响。它也不会影响PHP的用户空间输出缓冲机制。这意味着如果您正在使用ob_flush()和 flush() 来刷新ob输出缓冲区,则必须使用它们。

还有两种方法可以使PHP flush()每次您进行echo任何操作(或执行将输出回显到响应正文的任何​​其他操作)时自动调用。

首先是打电话ob_implicit_flush()。请注意,该函数被欺骗性命名。鉴于其ob_前缀,任何理智的人会认为它会影响到“输出缓冲”,因为这样做ob_startob_flush但是,这种情况并非如此;
ob_implicit_flush()像一样flush(),会影响服务器级别的输出缓冲区,并且不会与其他ob_功能控制的输出缓冲区发生任何交互。

第二种是通过在php.ini
中将implicit_flush标志设置为来全局启用隐式刷新On。这等效于ob_implicit_flush()在每个脚本的开头进行调用。



 类似资料:
  • 问题内容: 默认情况下,Python的解释器是否启用输出缓冲? 如果答案是肯定的,那么有什么方法可以禁用它? 到目前为止的建议: 使用命令行开关 包装每次写入后刷新的对象 设置环境变量 还有其他方法可以在执行过程中以编程方式在中设置一些全局标志吗? 问题答案: 你可以使用”python -u”()或通过设置环境变量PYTHONUNBUFFERED来跳过整个python进程的缓冲。 你还可以将替换为

  • 问题内容: 有一点问题。一直在使用facebook和twitter API并获取状态搜索查询的JSON输出没有问题,但是我进一步阅读并意识到,最终可能会受到文档中引用的“速率限制”。 我想知道每小时缓存JSON输出是否容易,以便至少可以尝试防止这种情况发生?如果是这样,怎么做?当我尝试一个youtube视频时,它并没有真正提供太多信息,只是如何将目录列表的内容写入到cache.php文件中,但是并

  • 问题内容: 当我使用Alamofire两次发送GET请求时,我得到的响应是相同的,但是我期望得到不同的响应。我想知道这是否是由于缓存造成的,如果是这样,我想知道如何禁用它。 问题答案: 迅捷3,alamofire 4 我的解决方案是: 为Alamofire创建扩展: 并使用它:

  • 问题内容: 如何使用文件快速关闭所有 Log4J 输出? 问题答案: 将级别设置为OFF(而不是DEBUG,INFO等)。

  • 我正在使用xslt转换xml文档。我需要使用输出转义来获得我的结果,因为我使用的工作服务器只会输出

  • 问题内容: 在我的Web应用程序中,当用户注销时,他应该无权访问他登录时先前查看过的页面。但是,由于浏览器缓存,他可以在单击后退按钮时查看这些页面。 我定义了一个拦截器来处理此问题: 并在: 发生的事情是,添加此代码后,运行应用程序时出现404错误。 我尝试在页面中添加响应标题: 但是必须将它一个接一个地添加到所有页面上是很麻烦的。另外,用户始终可以重新提交表单并再次访问那些页面,而无需实际输入其