【发布时间】:2018-10-15 06:34:44
【问题描述】:
我正在使用 PHP 函数来解析一个很长的字符串(shell_exec 命令的输出)。目前,该功能如下所示,并且工作正常。
/**
* @param string $result Output of shell command
* @return array $lines each line of output in array
*/
public function getLines($result)
{
$lines = [];
$expl = explode(PHP_EOL, $result);
foreach ($expl as $line) {
$lines[] = $this->funcFormatLine($line);
}
return $lines;
}
现在,我开始使用 generators in PHP,该函数看起来是重构使用它的好用例,因为爆炸输出数组很大并且会消耗一些内存。
我想要什么:
/**
* @param string $result Output of shell command
* @return string $line one line of output until end_of_line
*/
public function getLines($result)
{
$line = fancy_func_to_get_all_before_end_of_line_without_array(PHP_EOL, $result);
yield $line;
}
//somewhere in the function
foreach (getLines($result) as $line) {
doThings($this->funcFormatLine($line));
}
在第一种情况下,我有两个包含大量信息的数组($expl 和 $lines),在第二种情况下,我试图使用生成器来避免将这些内存用于数组。
我是否以某种错误的方式使用了生成器的概念?如果没有,是否可以在不爆炸字符串的情况下实现它然后yield $expl[$key]?
我尝试使用substr($string, $pos, strpos($string, PHP_EOL, $pos));,其中$pos 是字符串的位置,但我只能使用它调用一次getLines。
信息:
PHP 5.6
【问题讨论】:
-
将这个“非常长的字符串”保存在内存中很可能会在适当的时候引起它自己的问题。我建议将
shell_exec()切换为proc_open(),然后将您的生成器放在yield fgets($pipes[1]);上,然后在运行时直接从命令的标准输出中读取行。 -
实际上,我无法编辑从 shell 返回输出的代码,因为它用于系统的许多其他部分,但无论如何感谢您的提示,也许我尝试创建一个独占功能为它。
标签: php string iterator generator explode