Опператор GOTO (go to) в PHP

“Не используйте оператор goto” – так твердили нам преподаватели в академии, и действительно, оператор сей превращает код в полнейшую кашу. Разработчики php решили проблему кардинально – в php3 и php4 его просто нет. Чем они изначально руководствовались? Может быть хотели привить всем нам правильный стиль программирования? Ну что же, можно сказать это им вполне удалось – мы все уже привыкли, то есть вернее сказать начисто отвыкли от этого оператора, может оно и к лучшему, потому что в свое время мне пришлось придумать логическую конструкцию, которая вполне компенсировала этот самый злосчастный goto.
Не знаю у кого как, а у меня, особенно часто возникало желание использовать goto при создании обработчика html формы, когда от пользователя на сервер отправляется множество данных, которые 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); ?>

12345678910111213141516171819202122232425262728 <?phpdo { 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.’ ‘;</strong> 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(‘Принудительный останов цикла’) );

12345678910111213141516171819202122232425262728293031 DO {// в начале каждого цикла печатаем название// выполненной секции очень удобно для отладкиecho $action.‘ ‘;</strong> 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(‘Принудительный останов цикла’) );

Реальный обработчик формы конечно может быть намного сложней и обрабатывать данные в несколько форм-этапов. Моя скромная практика показала: такую конструкцию целесообразно применять для обработчиков средней сложности. Если же размер кода превышает 500-600 строк то тут без ООП уже не обойтись.