Zadejte hledaný výraz...

[N] PHP bude mít generátory

PHP získá v blízké budoucnosti generátory, tedy funkce, které umí postupně vracet hodnoty.
https://wiki.php.net/rfc/generators
function getLinesFromFile($fileName) {
if (!$fileHandle = fopen($fileName, 'r')) {
return;
}
while (false !== $line = fgets($fileHandle)) {
yield $line;
}
fclose($fileHandle);
}
$lines = getLinesFromFile($fileName);
foreach ($lines as $line) {
// do something with $line
}
Při prvním zavolání funkce, nazývané generator function, vrátí generátor. Generátor lze procházet pomocí foreach podobně jako pole.
Klíčem je nová konstrukce yield, která vrací částečnou hodnotu a umí při dalším požadavku pokračovat tam, kde skončila.
Více informací na odkazu výše.
5. 9. 2012 11:40:26
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804597
naniccz
verified
rating uzivatele
(3 hodnocení)
5. 9. 2012 12:01:45
Nedělá to totéž jako iterátory?
class FileLinesIterator implements Iterator {
$fileHandle = null;
$current = null;
$end = false;
public function __construct($fileName) {
if (!$this->fileHandle = fopen($fileName, 'r')) {
throw ...;
}
}
function next() {
$end = false === ($this->current = fgets($this->fileHandle));
}
function current() {
return $this->current;
}
function valid() {
return !$this->end;
}
// .. vč destruktoru na uzavření
}
5. 9. 2012 12:01:45
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804596
Sniper
verified
rating uzivatele
5. 9. 2012 12:42:23
hmmm, to vypada ze do jadra zakomponujou veci, co pridal facebook v HipHopu. Ti muze bejt fajn
5. 9. 2012 12:42:23
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804595
Petr Zachrdla
verified
rating uzivatele
(1 hodnocení)
5. 9. 2012 13:51:45
To sice vypadá zajímavě, ale jaké bude využití?
yield $line;
vs.
$temp[] = $line;
5. 9. 2012 13:51:45
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804594
Sniper
verified
rating uzivatele
5. 9. 2012 14:00:19
Bedrisek: napr. si aplikace nejdriv posbira jaka data potrebuje vytahnout z DB a pak je vytahne vsechna najednou. Peknej clanek o tom napsal Jakub Vrana na zacatku roku - http://php.vrana.cz/operator-yield.php
5. 9. 2012 14:00:19
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804593
Generátor vrací data postupně a může klidně generovat velmi dlouhou řadu bez zahlcení paměti, protože se vždy pracuje jen s jedním prvkem.
5. 9. 2012 14:05:25
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804592
Petr Zachrdla
verified
rating uzivatele
(1 hodnocení)
5. 9. 2012 14:47:16
Sniper - koukal jsem, ale není mi jasné fungování. fce getArticle, getArticleTags, getTagNames obsahují dotazy do databáze, které se neprovedou ihned, ale až v okamžiku yield result($article); s tím, že současně fce (gerArticle,getArticleTags ) jsou potřebné pro jinou fci a to se zpracuje rovněž až v tom posledním kroku yield result($article);? tím ušetřím transakční náklady. je to tak?
Martin - ok. a jaký je tedy rozdíl oproti array? existuje jiný způsob uložení v paměti yield $line a array?
5. 9. 2012 14:47:16
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804591
Generátor slouží k jednorázovému projití/vygenerování velké řady dat.
Funkce s yield si pamatuje stav, ve kterém byla při předchozím yield opuštěna a při dalším zavolání pokračuje v běhu, kde skončila.
Tady je ten princip dobře vysvětlený
http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained
Příklad Jakuba Vrány také nechápu.
5. 9. 2012 14:55:09
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804590
Petr Zachrdla
verified
rating uzivatele
(1 hodnocení)
5. 9. 2012 14:59:51
Napsal Martin Schlemmer;840806
Generátor slouží k jednorázovému projití/vygenerování velké řady dat.
Funkce s yield si pamatuje stav, ve kterém byla při předchozím yield opuštěna a při dalším zavolání pokračuje v běhu, kde skončila.
Tady je ten princip dobře vysvětlený
http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained
Příklad Jakuba Vrány také nechápu.
Jj. To jsem četl, ale stejně nevím jak se to liší od běžného array, kromě syntaxe.
5. 9. 2012 14:59:51
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804589
Petr Soukup
verified
rating uzivatele
(5 hodnocení)
5. 9. 2012 16:42:10
Je to takové... magické. Ale líbí se mi to. Řeší to problémy, kde se na jednoduché věci musely složitě vytvářet iterátory.
5. 9. 2012 16:42:10
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804588
Petr Soukup
verified
rating uzivatele
(5 hodnocení)
5. 9. 2012 16:44:21
Napsal Bedříšek;840810
Jj. To jsem četl, ale stejně nevím jak se to liší od běžného array, kromě syntaxe.
Pro vrácení pole musí proběhnout funkce až do konce a výsledky uložit do paměti. Tohle vrací výsledky postupně, takže to neobsazuje paměť. Navíc je možné přestat v půlce a nic moc se neděje. Představte si to třeba na funkci pro procházení složky - v případě array by se prošla celá složka a uložila do array. S generátorem se může procházet postupně a když najdu co hledám, tak procházet přestanu.
Samozřejmě že problémy které řeší generátor šly řešit už teď. Ale generátory je řeší velmi jednoduše.
5. 9. 2012 16:44:21
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804587
Petr Zachrdla
verified
rating uzivatele
(1 hodnocení)
5. 9. 2012 20:52:31
Napsal Souki;840858
Pro vrácení pole musí proběhnout funkce až do konce a výsledky uložit do paměti. Tohle vrací výsledky postupně, takže to neobsazuje paměť. Navíc je možné přestat v půlce a nic moc se neděje. Představte si to třeba na funkci pro procházení složky - v případě array by se prošla celá složka a uložila do array. S generátorem se může procházet postupně a když najdu co hledám, tak procházet přestanu.
Samozřejmě že problémy které řeší generátor šly řešit už teď. Ale generátory je řeší velmi jednoduše.
Děkuji za vysvětlení, ale bohužel mi to hlava nějak nebere. Mohl bych Tě poprosit o vysvětlení na Martinově příkladu?
5. 9. 2012 20:52:31
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804586
Petr Soukup
verified
rating uzivatele
(5 hodnocení)
5. 9. 2012 21:08:18
Napsal Bedříšek;840980
Děkuji za vysvětlení, ale bohužel mi to hlava nějak nebere. Mohl bych Tě poprosit o vysvětlení na Martinově příkladu?
Já to teda ještě nezkoumal, takže spíš hádám, jak to funguje.
function getLinesFromFile($fileName) {
if (!$fileHandle = fopen($fileName, 'r')) {
/** pokud soubor nejde otevřít (třeba neexistuje), tak se nevrací žádný výsledek*/
return;
}
/** postupně se čtou řádky souboru (a ukládají se do $line) dokud není konec souboru */
while (false !== $line = fgets($fileHandle)) {
yield $line; // každý řádek se vrátí (jakoby "return", ale funkce nekončí)
}
fclose($fileHandle);
}
$lines = getLinesFromFile($fileName);
foreach ($lines as $line) {
/* přes foreach se prochází postupně souborem a zpracovávají se řádky po jednom*/
}
Bez generátoru bychom dosáhli stejného výsledku takhle:
if ($fileHandle = fopen($fileName, 'r')) {
while (false !== $line = fgets($fileHandle)) {
echo $line;
}
fclose($fileHandle);
}
Konkrétně tady použití generátoru asi na první pohled nedává moc smysl, protože bez něj je to kratší. Trik je ale v tom, že můžeme mít univerzální generátor třeba na procházení adresáře a používat ho všude. Nebo třeba na získání produktů z databáze a generátor může vracet rovnou připravené objekty. Toho samého dosáhneme vytvořením třídy implementující Iterator, ale je s tím mnohem víc psaní.
5. 9. 2012 21:08:18
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804585
Petr Zachrdla
verified
rating uzivatele
(1 hodnocení)
5. 9. 2012 21:15:36
Napsal Souki;840993
Já to teda ještě nezkoumal, takže spíš hádám, jak to funguje.
function getLinesFromFile($fileName) {
if (!$fileHandle = fopen($fileName, 'r')) {
/** pokud soubor nejde otevřít (třeba neexistuje), tak se nevrací žádný výsledek*/
return;
}
/** postupně se čtou řádky souboru (a ukládají se do $line) dokud není konec souboru */
while (false !== $line = fgets($fileHandle)) {
yield $line; // každý řádek se vrátí (jakoby "return", ale funkce nekončí)
}
fclose($fileHandle);
}
$lines = getLinesFromFile($fileName);
foreach ($lines as $line) {
/* přes foreach se prochází postupně souborem a zpracovávají se řádky po jednom*/
}
Bez generátoru bychom dosáhli stejného výsledku takhle:
if ($fileHandle = fopen($fileName, 'r')) {
while (false !== $line = fgets($fileHandle)) {
echo $line;
}
fclose($fileHandle);
}
Konkrétně tady použití generátoru asi na první pohled nedává moc smysl, protože bez něj je to kratší. Trik je ale v tom, že můžeme mít univerzální generátor třeba na procházení adresáře a používat ho všude. Nebo třeba na získání produktů z databáze a generátor může vracet rovnou připravené objekty. Toho samého dosáhneme vytvořením třídy implementující Iterator, ale je s tím mnohem víc psaní.
ok. díky. tak to zatím chápu stejně, ale to se nijak neliší od
$temp[] = $line;
...
return $temp;
protože ta informace zabere v paměti stejně místa, lze s ní stejně manipulovat (array)
5. 9. 2012 21:15:36
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804584
Petr Soukup
verified
rating uzivatele
(5 hodnocení)
5. 9. 2012 21:25:11
Napsal Bedříšek;840996
ok. díky. tak to zatím chápu stejně, ale to se nijak neliší od
$temp[] = $line;
...
return $temp;
protože ta informace zabere v paměti stejně místa, lze s ní stejně manipulovat (array)
Pokud budeme mít dvě funkce, kde jedna přečte 1000 řádků souboru a vrátí je jako pole a druhá bude generátor, který je vrací postupně, tak ta první zabere v paměti (zhruba) 1000x víc místa.
5. 9. 2012 21:25:11
https://webtrh.cz/diskuse/n-php-bude-mit-generatory#reply804583
Pro odpověď se přihlašte.
Přihlásit