2016-06-15 7 views
7

昨日、私はPHPにyield()メソッドがあることを学びました。私はPHPでのその有用性については不安でした。PHP収量対PDO取得?

同僚は、それが潜在的なメモリの問題を引き起こし、多くの行を返すSQL文のために役立つかもしれないと述べました。彼はfetchAll()を参照していたと思います。 しかし、fetchAll()を使用する代わりに、fetch()を使用して、行を1つずつ処理することもできます。だから、yield()は、彼が指摘している問題を解決する鍵ではありません。

は、私がここにfetch()対についてyield()何かが足りないのですか? yield()とジェネレータを使用すると、より多くの利点がありますか?

P.S:それはfetch()とよりもyield()を持つ大規模なアプリケーションでは、クリーン読めるとmaitainableコードを記述する方が簡単です事実です。

+3

、PDOは、降伏usefilnessのための非常に良い例ではないPDO理由文はすでにトラバース可能なインタフェースを実装しており、foreachを使用して反復することができます。しかし、mysqliを使うと、yieldを使ってmysqliの結果をforeachで繰り返すことができます。 –

+1

まあ、一般的に、これは*ジェネレータ*が役に立つものになります( 'yield 'はジェネレータの実装の詳細なので)。そしてジェネレータは、配列(または* iterable *)のように動作するが、すべてのデータをメモリに格納せず、必要に応じて各繰り返しで*生成するものを作成するのに便利です。はい、これはデータベース結果を取得するコンテキストで使用できますが、無限カウンターや他の多くのものを実装するために使用することもできます。 – deceze

答えて

9

したがってyield()は、彼が参照している問題を解決するための鍵ではありません。

正確に。

しかし、メモリオーバヘッドもなく、foreach()コールとして、while()/fetch()シーケンスを偽装することができます。

しかし、PDOはPDOStatementが既に通行可能インターフェースので、can be iterated over using foreach()を実装しているため、非常に良い例ではありません。

$stmt = $pdo->query('SELECT name FROM users'); 
foreach ($stmt as $row) 
{ 
    var_export($row); 
} 

それでは、唯一の一つ一つの結果をストリーミングすることができます例えば、APIのmysqliのを見てみましょう。
編集。実際にはsince 5.4.0 mysqli supports Traversableも同様です。したがって、mysqli_resultを使用してyieldを使用することには意味がありません。しかし、私は、実証目的のためにそれを保ちましょう。

のは、この

function mysqli_gen (mysqli_result $res) 
{ 
    while($row = mysqli_fetch_assoc($res)) 
    { 
     yield $row; 
    } 
} 

のようなジェネレータを作成してみましょう、今あなたがオーバーヘッドなしのforeachを使用して行を取得することができます:まあ

$res = $mysqli->query("SELECT * FROM users"); 
foreach (mysqli_gen($res) as $row) 
{ 
    var_export($row); 
}