while (condition) { ... } выполняет блок снова и снова, пока условие истинно. Условие проверяется перед каждым проходом, поэтому если оно ложно с самого начала, тело не выполнится ни разу. Что-то внутри цикла должно менять условие, иначе он никогда не закончится.
Это как раз тот тип задачи, для которого создан while: число проходов заранее неизвестно, известно только, когда остановиться. Измените процентную ставку и запустите снова.
do while: хотя бы один раз
do { ... } while (condition); проверяет условие после тела, поэтому тело всегда выполняется один раз. Обратите внимание на точку с запятой в конце.
Типичное применение это "попробовать, потом проверить": бросать кубик, пока не выпадет шестёрка, генерировать код, пока не найдётся свободный. Первая попытка должна случиться раньше, чем появится что проверять. Этот код даёт разный результат при каждом запуске:
while (true) с break
Когда условие выхода удобнее проверять в середине тела, пишите while (true) и выходите через break. continue переходит к следующей проверке, как в любом цикле.
array_shift() возвращает null, когда массив опустел, и это второй способ выйти. Тот же цикл можно записать как while ($queue), потому что пустой массив считается ложным.
Чтение файла построчно
fgets() возвращает по одной строке и false в конце файла, поэтому сама управляет циклом while. Блок сначала записывает файл, а потом читает его обратно.
Скобки вокруг $line = fgets($handle) важны: сначала происходит присваивание, затем результат сравнивается с false. Проверка !== false вместо простой проверки на истинность не даёт последней строке, содержащей только 0 (без переноса после него), досрочно завершить цикл. Функции для работы с файлами описаны на странице про fopen().
while с endwhile в шаблонах
Как и у if и for, у while есть форма с двоеточием для HTML: while (...): и endwhile;. Этот код выводит список обратного отсчёта во вкладке Page.
Частая ошибка: цикл, который никогда не заканчивается
Счётчик должен двигаться к выходу. Забудьте $i++ или измените не ту переменную, и условие останется истинным навсегда. На веб-сервере PHP остановит скрипт через max_execution_time (по умолчанию 30 секунд) с фатальной ошибкой. В командной строке он не остановится никогда.
// Never ends: $i is never changed
$i = 0;
while ($i < 3) {
echo $i;
}
Ограничение на число попыток это дешёвая защита для циклов, которые зависят от внешних данных, например повтора вызова или постраничного получения результатов:
Запустите несколько раз: иногда он быстро добивается успеха, иногда сдаётся, но всегда заканчивается. Когда число проходов известно заранее, цикл for задаёт начало, конец и шаг в одной строке, и ошибиться с ним труднее.
Часто задаваемые вопросы
Чем while отличается от do while в PHP?
while проверяет условие перед каждым проходом, поэтому тело может не выполниться ни разу. do { ... } while ($cond); проверяет после каждого прохода, поэтому тело всегда выполняется хотя бы раз. Обратите внимание на точку с запятой после условия do while.
Как остановить бесконечный цикл while в PHP?
Внутри цикла завершите его через break, когда выполнено условие выхода: while (true) { ...; if ($done) { break; } }. Если в цикле нет break, а его условие никогда не становится ложным, скрипт работает, пока его не остановит max_execution_time (веб-запросы), или вечно (командная строка).
Когда использовать while вместо for в PHP?
Используйте while, когда неизвестно, сколько понадобится проходов: чтение до конца файла, повтор до успеха, обработка очереди, пока она не опустеет. Используйте for, когда считаете, и foreach, чтобы пройти каждый элемент массива.
Есть ли в PHP цикл do until?
Нет. Инвертируйте условие остановки в do while: do { $n++; } while (!($n >= 3)); работает, пока $n >= 3 не станет истинным. until не является ключевым словом PHP.