Немаловажное про генераторы в PHP
Наткнулся на важный пост о генераторах в ПХП, я их попробовал использовать, ещё когда они были в альфе. Хорошая штука, мне после Пайтона их в языке не хватало.
Суть же рассматриваемой проблемы в следующем. Смотрите, вот функция, которая возвращает построчно файл и пример её вызова:
function getLines($file) {
$f = fopen($file, 'r');
while ($line = fgets($f)) {
yield $line;
}
fclose($f);
}
foreach (getLines("file.txt") as $line) {
echo $line;
}Пока всё чудесно, ничего странного и необычного, а теперь представьте, что нам нужно прочитать только четыре первые строки:
foreach (getLines("file.txt") as $n => $line) {
if ($n > 5) break;
echo $line;
}Если в файле их было больше, то в функции getLines вызов fclose не выполнится никогда — до него программа просто не дойдёт, файл останется открытым, память занятой и так далее. Плохо. Что делать?
Оказывается, документация обходит этот вопрос стороной, а вот автор введения в ПХП этой конструкции позаботился о том, чтобы эту тему раскрыть — если прочитать соответствующий RFC, становится ясно как быть.
Оказывается, при высвобождении ссылки на генератор, внутри его обязаны выполнится все блоки finally, т. е. вышеприведённый код нужно переписать следующим образом:
function getLines($file) {
$f = fopen($file, 'r');
try {
while ($line = fgets($f)) {
yield $line;
}
} finally {
fclose($f);
}
}
Комментарии 15
Если бы пхп был асинхронным -- богом дарованная штука, а в синхронном пхп ну зачем они?
Почему их именно «не хватало» если это не более чем сахар.
Пока писал это, вспомнил, что у Вани была статья, касающаяся генераторов, которая поможет понять одну из областей где они полезны: http://softwaremaniacs.org/blog/2010/09/18/ijson/
ну с ФС проблемы не существует.
с БД не прокатит.
ЖСОН и прочие сериализованные данные, на мой взгляд, универсально парсить не получится.
не понимаю :).
Комментарий для Евгения Степанищева:
Я, как сова, не очень вник, но потом дочитаю. На первый взгляд я понял что оно возращает key:value из жсона и это круто потому что не жрётся память, но если value будет охеренным объектом -- уже бесполезно.
А делать рекурсивные вхождения -- непонятно как потом обрабатывать.
Я, вроде, понимаю зачем нужны генераторы, но рассматриваю их исключительно как сахар. Хотя надо попробовать поиграться чтоли.
Комментарий для Евгения Степанищева:
Ну тут я оказался неправ, но автор пишет что у него получится приррост по скорости 30%. При этом обрабатывать это неудобно. То есть да, для оптимизации можно пользовать, но лучше хранить код красивым если есть возможность :).
Код будет красивым :)
http://david-m.livejournal.com/1294116.html
А разве у вас не включено автоматическое исправление ошибок?
Комментарий для 4idroid.com:
Не включено автоматическое исправление ошибок где?