Использование php yield / Generator :: send () для & quot; потока вывода данных & quot;

Я знаю, что yield можно использовать для создания итератора данных, например, читать данные из файла CSV.

function csv_generator($file) {
$handle = fopen($file,"r");
while (!feof($handle)) {
yield fgetcsv($file);
}
fclose($file);
}

Но метод Generator :: send () предполагает, что я могу сделать то же самое для последовательной записи вместо чтения.

Например. Я хочу использовать такую ​​вещь:

function csv_output_generator($file) {
$handle = fopen('file.csv', 'w');
while (null !== $row = yield) {
fputcsv($handle, $row);
}
fclose($handle);
}

$output_generator = csv_output_generator($file);
$output_generator->send($rows[0]);
$output_generator->send($rows[1]);
$output_generator->send($rows[2]);
// Close the output generator.
$output_generator->send(null);

Выше будет работать, я думаю.

Но $output_generator->send(null); для закрытия кажется неправильным или не идеальным. Это означает, что я никогда не смогу отправить буквальный ноль. Что нормально для написания CSV, но, возможно, есть вариант использования для отправки нулевого значения.

Есть ли «лучшие практики» для использования php-генераторов для последовательной записи?

4

Решение

Не сказать, что это изумительная идея, но если вы говорите о семантике, это «здорово».

Проверьте против класса. Как передать объекты определенного класса, чтобы завершить генератор. Подобно:

// should probably use namespacing here.
class GeneratorUtilClose {}

class GeneratorUtil {
public static function close() {
return new GeneratorUtilClose;
}
}

function csv_output_generator($file) {
$handle = fopen('file.csv', 'w');

while (!(($row = yield) instanceof GeneratorUtilClose)) {
fputcsv($handle, $row);
}

fclose($handle);
}

$output_generator = csv_output_generator($file);
$output_generator->send($rows[0]);
$output_generator->send(GeneratorUtil::close());

Здесь добавлена ​​небольшая фабрика для дополнительного семантического сахара.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]