我知道yield可用于创建数据迭代器,例如从CSV文件中读取数据。
function csv_generator($file) {
$handle = fopen($file,"r");
while (!feof($handle)) {
yield fgetcsv($file);
}
fclose($file);
}
但是Generator :: send()方法表明我可以为顺序写入做同样的事情,而不是阅读。
E.g。我想用这样的东西:
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);
关闭似乎是错误的,或者不理想。这意味着我永远不会发送文字null。这对于csv编写是可以的,但也许有一个用例来发送null。
使用php生成器进行顺序编写是否有“最佳实践”?
答案 0 :(得分:1)
不是说这是一个了不起的想法,但如果你说的是语义,那么这就是“感觉”。大。
检查班级。像传递特定类的对象来终止生成器一样。像:
objMyCmd.CommandText = "IF (Select object_id('TempDB..#Step1')) IS NOT NULL" & _
" Begin " & _
" Drop Table #Step1 " & _
" End " & _
" SELECT a.[RDT_FileID],a.[Master Policy Number], a.[Work item /Submission no#],a.[Insured Name], a.[Credited Office], " & _
" a.[Credited Underwriter], a.[Product Line], a.[Product Line Subtype], a.[Current Status], a.[Effective Date], a.[Expiry Date], a.[Premium in USD $] " & _
" INTO #Step1 " &_
" FROM dbo.View_Property_Rater_Of_Record a " & _
" WHERE a.[Master Policy Number] Is Not Null " & _
" AND a.[RDT_FileID] is null " & _
" AND a.[Product Line Subtype] <> '0102-Marine' " & _
" AND a.[Effective Date] >= '2014-04-01' " & _
" SELECT * from #Step1 WHERE [Current Status] ='Bound' "
在这里添加了一个小工厂,以获得额外的语义糖。
答案 1 :(得分:0)
也不理想,但无需创建任何其他类即可工作
function csv_output_generator($file) {
$handle = fopen($file, 'w');
try {
while ($row = yield) {
fputcsv($handle, $row);
}
} catch (ClosedGeneratorException $e) {
// closing generator
}
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->throw(new ClosedGeneratorException());