Goto нет в php, а иногда так хочется.
“Не используйте оператор goto” – так твердили нам преподаватели в академии, и действительно оператор сей превращает код в полнейшую кашу. Поэтому разработчики php решили проблему кардинально – в php его просто нет. Но иногда очень хочется, чтобы он все таки был особенно когда пишешь обработчик какой-то формы где пользователь должен ввести сложный набор данных, а мы должны их обработать. Процесс этот проходить, как правило, в несколько этапов: печать самой формы, проверка полученных данных, предварительны показ, ну и например сохранение. Причем некоторые этапы могут повторятся : если проверка данных не прошла удачно переходим на печать формы, или если предварительный показ не устроил пользователя он может вернутся к вводу данных. Короче говоря некоторые куски кода могут задействоваться многократно. Использовать функции в этих условиях тоже не очень удобно – много входных и выходных переменных, функция должна выполнять слишком сложные действия, вообще коряво получается и читабельность кода резко падает.
И я придумал такую вот конструкцию.
<?php do { switch ($action) { default: break; case 'PRINT_FORM': /* печатаем главную форму */ break; case 'CHECK_FORM': /* проверяем правильность данных */ break; case 'PREVIEW_FORM': /* предворительный просмотр */ break; case 'SAVE_FORM': /* сохраняем данные */ break; } } while (true); ?>
Здесь основной оператор множественного выбора switch заключен в бесконечный цикл do-while – таким образом мы группируем нужные действия в секциях case : break; и можем неограниченно переходить из одной секции к другой. В секции default: удобно сделать предварительный разбор данных например если входных данных нет то $action = ‘PRINT_FORM’ печатаем форму, если есть например $_POST [‘submit’] то тогда отправляем на обработку полученных данных $action = ‘CHECK_FORM’ . Передача управления между блоками switch происходит с помощью изменения переменной $action, ну а выход из цикла с помощью break 2; или exit;
Так например в блоке печати основной формы можно смело поставить break 2; т.к вывод формы предполагает окончание скрипта.
Конструкция очень гибкая и читабельная. Но есть один недостаток – если неправильно обработаны данные можно попасть в бесконечный цикл и скрипт зависает - это неприятно придется ждать целых 30 сек.
Давайте установим ограничение на кол-во циклов оператора do-while, 20 хватит с головой. Теперь если мы что-то накасячили скрипт намотает 20 оборотов, остановится и вывалит предупреждение об екстренном останове.
Отлаживать такую кострукцию очень удобно - достаточно после оператора swith распечатывать переменную $action и мы получим полную последовательность исполнения блоков.
DO { // в начале каждого цикла печатаем название // выполненной секции очень удобно для отладки echo $action.' '; SWITCH ($action) { default: break; case 'PRINT_FORM': /* печатаем главную форму */ break; case 'CHECK_FORM': /* проверяем правильность данных */ break; case 'PREVIEW_FORM': /* предворительный просмотр */ break; case 'SAVE_FORM': /* сохраняем данные */ break; }// end switch } WHILE ( ( ($i++) < 20 ) or die('Принудительный останов цикла') );
Реальный обработчик формы конечно может быть намного сложней и обрабатывать данные в несколько форм-этапов. Хотя конечно можно все размазать по разным скриптам, и использовать функции для группировки кода тут уже дело вкуса.