I know that yield can be used to create a data iterator, e.g. to read data from a CSV file.
function csv_generator($file) {
$handle = fopen($file,"r");
while (!feof($handle)) {
yield fgetcsv($file);
}
fclose($file);
}
But the Generator::send() method suggests that I can do the same for sequential writing, instead of reading.
E.g. I want to use the thing like this:
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);
The above will work, I think.
But $output_generator->send(null);
for closing seems wrong, or not ideal. It means that I can never send a literal null. Which is ok for csv writing, but maybe there is a use case for sending null.
Is there any "best practice" for using php generators for sequential writing?
Not saying this is a marvelous idea but if you're talking semantics, this 'feels' great.
Check against a class. Like pass in objects of a particular class to terminate the generator. Like:
// 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());
Added a little factory in here for extra semantic sugar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With