PHP:尝试让 fgets() 在 CRLF、CR 和 LF 上触发

2024-01-11

我正在使用 proc_open 和 fgets($stdout) 读取 PHP 中的流,尝试获取传入的每一行。

许多 Linux 程序(包管理器、wget、rsync)仅使用 CR(回车)字符来表示定期“就地”更新的行,例如下载进度。我希望在这些更新发生后立即捕获它们(作为单独的行)。

目前, fgets($stdout) 只是继续读取直到 LF,因此当进度非常缓慢(例如大文件)时,它只会继续读取直到完全完成,然后将所有更新的行作为一个长字符串返回,包括CR。

我尝试设置“mac”选项来检测 CR 作为行结尾:

ini_set('auto_detect_line_endings',true); 

但这似乎不起作用。

现在,stream_get_line 允许我将 CR 设置为换行符,但不是将 CRLF、CR 和 LF 视为分隔符的“包罗万象”解决方案。

我当然可以读取整行,使用各种 PHP 方法将其分割,并用 LF 替换所有类型的换行符,但它是一个流,我希望 PHP 能够在其仍在运行时获得进度指示。

所以我的问题是:

如何从 STDOUT 管道(从 proc_open)读取 LForCR发生,而不需要等到整条线都进来?

提前致谢!

解决方案:

我使用 Fleshgrinder 的过滤器类在流中将 \r 替换为 \n (请参阅接受的答案),并将 fgets() 替换为 fgetc() 以获得对 STDOUT 内容的更多“实时”访问:

$stdout = $proc->pipe(1);
stream_filter_register("EOL", "EOLStreamFilter");
stream_filter_append($stdout, "EOL"); 

while (($o = fgetc($stdout))!== false){
    $out .= $o;                            // buffer the characters into line, until \n.
    if ($o == "\n"){echo $out;$out='';}    // can now easily wrap the $out lines in JSON
}

在使用流之前,使用流过滤器标准化新行字符。我创建了以下代码,该代码应该根据 PHP 手册页中的示例来实现此目的stream_filter_register https://php.net/stream-filter-register.

代码未经测试!

<?php

// https://php.net/php-user-filter
final class EOLStreamFilter extends php_user_filter {

    public function filter($in, $out, &$consumed, $closing)
    {
        while ($bucket = stream_bucket_make_writeable($in)) {
            $bucket->data = str_replace([ "\r\n", "\r" ], "\n", $bucket->data);
            $consumed += $bucket->datalen;
            stream_bucket_append($out, $bucket);
        }
        return PSFS_PASS_ON;
    }

}

stream_filter_register("EOL", "EOLStreamFilter");

// Open stream …

stream_filter_append($yourStreamHandle, "EOL");

// Perform your work with normalized EOLs …

EDIT:马克·贝克对你的问题发表的评论是正确的。大多数 Linux 发行版都使用行缓冲区STDOUT苹果可能也在做同样的事情。另一方面大多数STDERR流是无缓冲的。您可以尝试将程序的输出重定向到另一个管道(例如STDERR或任何其他),看看你是否有更多的运气。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP:尝试让 fgets() 在 CRLF、CR 和 LF 上触发 的相关文章

随机推荐

  • Facebook 需要 CURL PHP 扩展

    我正在尝试在我的 apache 服务器上运行我的第一个 facebook php 应用程序 它给出了错误Facebook needs the CURL PHP extension 我已经添加了行extension php curl dll在
  • 哪个版本的 Grails 支持 JDK 8?

    我正在为 Grails 使用以下配置 Grails 版本 2 4 0 Maven版本3 2 5 JDK版本1 8 0 51 当我运行服务器时 我收到两个错误 在我的 POM 中 我使用grail gorm and grail crud依赖关
  • 使用 ruby​​/fastercsv 将 CSV 文件合并到公共字段上

    我有一个包含许多列的 主 文件 1 2 3 4 5 我还有一些其他文件 其行数比主文件少 每个文件的列数 1 6 我想合并这些匹配的文件在第 1 列字段上并将第 6 列添加到主字段 我见过一些 python UNIX 解决方案 但如果合适的
  • 加载数据问题

    数据链接 Data https www dropbox com s yt4l10nel5bwxoq GTAP ConsIndex csv Code ccfsisims lt read csv file F Purdue University
  • VS2010:自动生成的文件和 XML 文档

    这真的只是重新询问这个问题询问有关 Visual Studio 2008 https stackoverflow com questions 1445723 vs2008 autogenerated files and xml docume
  • Django 管理表格内联查找选择下拉框用于非常大的查询集

    我有一个 django admin 表格内联 其中我有form ProdForm其中持有一个modelchoicefield选择框如下 class ProdForm forms ModelForm productid forms Model
  • 分叉与线程

    我以前在我的应用程序中使用过线程并且很了解它的概念 但最近在我的操作系统讲座中我遇到了 fork 这与线程类似 我用谷歌搜索了它们之间的区别 我发现 Fork只不过是一个新进程 看起来与旧进程或父进程一模一样 但它仍然是一个不同的进程 具有
  • 当我在 iOS13.2 中加载 WKWebView 时,为什么会收到控制台警告:[Process] Kill() 返回意外错误 1?

    自从我安装了iOS 13 2 测试版 我收到了调试控制台错误消息 每次我在情节提要中加载带有 WKWebView 对象的 ViewController 时 都会发生这种情况 然后 当 Web 视图可见时 会连续显示以下消息 2019 10
  • Cordova SQLite:无法读取 null 的属性“事务”

    我正在尝试将 SQLite 集成到我的 Ionic 应用程序中 但我不断收到Cannot read property transaction of null通过浏览器进行远程调试或测试时 尝试在数据库中查询设备上的数据时 因此 我将所有配置
  • xml.etree 还是 xml.dom?

    我正在尝试读取一些 xml 但我不确定应该使用哪个库 xml etree 和 xml dom 哪个更好 为什么 请解释你的答案并给出论点 另外 您认为其中之一会被弃用吗 哪一个 两者都不会被弃用 元素树 http effbot org zo
  • 多个插入的行 ID

    我一次插入多行 如下所示 INSERT INTO person VALUES joe 50 jon 24 然后我需要使用他们的 id 将上面的内容链接到另一个表 通常我会使用LAST INSERT ID INSERT INTO hobbie
  • 如何使用 JavaScript 统计我网站上的访问者数量?

    我需要一个计数器来集成到我的 HTML 代码中 当访问者访问我的网页时 该计数器从一计数到三 例如 如果第一个访问者访问我的页面 则计数为 1 那么下一个访问者访问该页面 则计数为 2 对于第三个访问者 计数为 3 然后对于第四个访问者 又
  • 如何查看google app脚本项目的源代码?

    所以我想以任何方式知道 我们是否可以看到提供了以 exec 结尾的 Web 应用程序 URL 的应用程序脚本项目的源代码 提前致谢 如果您不拥有该脚本或在 Google 云端硬盘中没有与您共享该脚本 则无法查看服务器端代码
  • 不单击所有选项卡并且不循环一次问题

    I am trying to click the tabs on the webpage as seen below Unfortunately it only seems to click some of the tabs despite
  • 基于包含子查询的查询的 ms-access 交叉表查询

    我在基于包含子查询的查询的交叉表查询时遇到问题 查询本身工作正常 但是当我在交叉表查询中使用它时 我收到一条与无法识别的字段名称相关的错误消息 并指向子查询中使用的字段 奇怪的是 我可以毫无问题地在此查询上定义数据透视表或数据透视图 所以
  • Chrome 扩展 - 获取当前选项卡的全部文本内容

    我正在开发一个扩展 我需要获取当前选项卡上的整个文本内容 现在我有一个插件可以从当前选项卡中检索选定的文本 所以 本质上我正在寻找它的 ctrl A 版本 这就是我到目前为止根据 Derek 的提示所做的事情 这是在我的事件处理程序中 这只
  • 当 python2.7 运行良好时,python 3.3 出现缩进错误

    我在下面编写了这个脚本 它将数字转换为其拼写 no raw input Enter a number strcheck str no try val int no except ValueError print sayi degil rai
  • Visual Studio 2010 中的 global.asax.cs 在哪里

    我安装的模板中不再有全局应用程序类代码隐藏 我只有 Global asax 我发现与全局 asax cs 为什么我再也看不到它了 如何重新创建Global asax cs 这是因为您创建的是网站而不是 Web 应用程序 我建议您使用预编译的
  • Kotlin 脚本文件中仅部分语法突出显示

    我在 Android Studio 中打开了一个文件夹 其中包含一个 Kotlin 脚本文件 kts 我在项目结构中配置了 JDK 作为 SDK 但我没有添加 gradle 文件 并且作为 Kotlin 脚本运行该文件工作正常 然而 语法突
  • PHP:尝试让 fgets() 在 CRLF、CR 和 LF 上触发

    我正在使用 proc open 和 fgets stdout 读取 PHP 中的流 尝试获取传入的每一行 许多 Linux 程序 包管理器 wget rsync 仅使用 CR 回车 字符来表示定期 就地 更新的行 例如下载进度 我希望在这些