【发布时间】:2017-03-15 22:55:39
【问题描述】:
我知道 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 编写来说是可以的,但也许有一个发送 null 的用例。
有没有使用php生成器进行顺序编写的“最佳实践”?
【问题讨论】:
-
这不仅仅是生成器的问题。您确实有
while (!feof($handle)),您需要在到达文件末尾后检查 1 次。这是同样的问题。 -
好吧,我们在这里讨论语义。您也可以发送
true、false、null等。这是您的电话。你用nulltho 提出了一个公平的观点。我不知道,我想我会发送一些冗长的字符串之类的东西,但这也是我不设计系统的原因,这可能是一个可怕的想法。 -
@apokryfos 但由于 feof() 是一个单独的函数,它不会限制 fgetcsv() 可能返回值的范围。当然这对 csv 毫无意义,因为如果 fgetcsv() 返回 null,我们就知道它是 EOF。输入迭代器已经为 ->valid() 和 ->current() 设计了单独的方法,因此 ->current() 可以返回 null 而不意味着 EOF。但不适用于输出/写作。
-
@Andrew 我选择了 null 因为如果没有发送任何内容,yield 已经碰巧返回 null。是的,我可以为此选择不同的魔法值。但理想情况下,我不会使用 send() 方法来关闭流,而是使用专用的 ->close() 方法。 (不存在)。
-
顺便说一句 ->close() 方法有时对阅读也很有用。例如。在 EOF 之前关闭 csv 文件句柄。
标签: php php-generators