2016-06-15 28 views
7

Wczoraj dowiedziałem się, że PHP ma metodę yield(). Nie byłem pewien co do jego przydatności w PHP.Wynik PHP vs pobranie PDO?

Kolega powiedział, że może to pomóc w SQL powracających wiele wierszy powodujących potencjalne problemy z pamięcią. Sądzę, że odnosił się do fetchAll(). Ale zamiast używać fetchAll(), można również użyć fetch() i procesowych wierszy jeden po drugim. Tak więc, yield() nie jest kluczem do rozwiązania problemu, do którego się odnosi.

jestem brakuje czegoś o yield() vs fetch() tutaj? Czy korzystanie z yield() i generatorów ma więcej zalet?

P.S .: To prawda, że ​​łatwiej jest napisać czysty, czytelny i maitainable kod w dużych aplikacjach yield() niż zz fetch().

+3

No PDO nie jest bardzo dobrym przykładem dla dochodowości usefilness, ponieważ PDO Instrukcja już implementuje interfejs, który można przełączyć i może być iterowany za pomocą foreach. Ale z mysqli możesz użyć yield, aby wynik mysqli był iterowany z foreach. –

+1

Generalnie sprowadza się to do tego, do czego * generatory * są użyteczne (ponieważ 'yield' jest szczegółem implementacji generatorów). Generatory są przydatne do tworzenia czegoś, co zachowuje się jak tablica (lub raczej * iterable *), ale nie przechowuje wszystkich swoich danych w pamięci, ale * generuje * ją z każdą iteracją w razie potrzeby. Tak, może to być używane w kontekście pobierania wyników bazy danych, ale może być również użyte do zaimplementowania nieskończonego licznika lub dowolnej liczby innych rzeczy. – deceze

Odpowiedz

9

Tak więc yield() nie jest kluczem do rozwiązania problemu, do którego się odnosi.

Dokładnie.

Ale może pozwolić Ci ukryć sekwencję while()/fetch() jako wywołanie foreach(), jeśli wolisz, bez dodatkowego obciążenia pamięci.

Jednakże PDO nie jest bardzo dobrym przykładem, ponieważ PDOStatement już implementuje przesuwny interfejs, a tym samym can be iterated over using foreach():

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

Więc weźmy mysqli na przykład API, które tylko strumień powoduje jeden po drugim.
Edit. W rzeczywistości, since 5.4.0 mysqli supports Traversable również, więc nie ma sensu używać wydajności z mysqli_result. Ale, trzymajmy to dla celów demonstracyjnych.

Stwórzmy generator jak ten

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

a teraz można dostać rzędy za pomocą foreach bez narzutu:

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