Используйте функцию разнесения в функции генератора, чтобы перебрать длинную строку в PHP - PullRequest
0 голосов
/ 04 мая 2018

Я использую функцию 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;
}

Теперь я начинаю использовать генераторы в 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 один раз, используя ее.

INFO:

PHP 5,6

1 Ответ

0 голосов
/ 04 мая 2018

Пример использования генератора при извлечении строк из фрагмента текста. Он имеет цикл для поиска строк одна за другой и использует yield для передачи каждого сегмента по одному за раз.

function getLines( $result )    {
    $start = 0;
    while (($end = strpos($result, PHP_EOL, $start)) !== false)   {
        $line = trim(substr($result, $start, $end - $start));
        yield $line;
        $start = $end+1;
    }
}

foreach ( getLines($test) as $line)  {
    echo ">".$line."<".PHP_EOL;
}

Как видите, возвращаемое значение вызова функции используется для управления foreach и вывода каждой строки в $line.

В этом коде $test - строка для анализа.

...