Много за и против. Может на других языках без goto и можно обойтись, но помогите понять или рефакторить приведённый код, чтоб ы дальнейшем пытаться обойтись без оператора goto в php или нет.. ПС: Частая ситуация, что на одной страниуе есть вохможность редактирования и добаления данных, отсюда $_POST дополнительную вложенность данных за счёт ветвления. ППС: без ООП стиля. Версия без goto Код (PHP): <?php if ($_POST === редактирование) { // ... } elseif ($_POST === добавление) { // входные данные надо проверять, фильтровать //в случае успеха или проблем отправлять пользователю сообщения //так как обращение к несуществующему индексу в массиве в PHP может привести к ошибке: if ( isset($_POST['поле_данных_1']) ) { //теперь надо проверить, что данные не пустые if ( strlen($_POST['поле_данных_1']) > 2 ) { //данные не должны начинаться с цифры if ( preg_match('~\d~', $_POST['поле_данных_1']) !== 1 ) { // что-то делаем с данными // ... // что-то делаем с данными } else { //сообщение o некорректном формате данных } } else { //сообщение об некорректной длинне данных } } else { //сообщение об некорректных данных } } Если полей данных несколько, то "что-то делаем с данными" выносим в функцию и код растёт в подобном ключе. Читать такую вложенность не то, что сложно, иногда просто не возможно.. Версия с goto Код (PHP): <?php if ($_POST === редактирование) { // ... } elseif ($_POST === добавление) { if ( isset($_POST['поле_данных_1']) ) { //сообщение об некорректных данных goto label_PostEND; } if ( strlen($_POST['поле_данных_1']) > 2 ) { //сообщение об некорректной длинне данных goto label_PostEND; } if ( preg_match('~\d~', $_POST['поле_данных_1']) !== 1 ) { goto label_PostEND; //сообщение o некорректном формате данных } // что-то делаем с данными // ... // что-то делаем с данными } label_PostEND: Немного слукавил, убрав коментарии во втором варианте, но это не суть вопроса. PHP, JavaScript, SQL и другой код пишите внутри тегов Код ( (Unknown Language)): [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
насчет goto... Его использовали в языках низкого уровня, вместо циклов или ветвления. На сегодня, если ты используешь goto, то это говорит о том, что ты не совсем понимаешь о процессе обработки данных языка программирования, то беш - недостаточно владеешь знанием программирования, что бы обойтись без goto. Набивай пальчики и поднимай свой уровень со своим стилем программирования (;
Можно использовать return из функции проверки POST запроса. Возвращать можно хоть строку, хоть код, например: Код (PHP): function checkPost(){ if(isset($_POST['поле_данных_1'])){ return 1;//сообщение об некорректных данных } if(strlen($_POST['поле_данных_1']) > 2){ return 2;//сообщение об некорректной длинне данных } if(preg_match('~\d~', $_POST['поле_данных_1']) !== 1){ return 3;//сообщение o некорректном формате данных } return 0; } После проверки функцией уже будет определенность, какие именно данные пришли, верные или нет. Далее выводить можно либо через switch: Код (PHP): $result = checkPost();//в $result код - результат проверки switch($result){ case 0: //все ок, вроде, обрабатываем данные break; case 1: //сообщение об некорректных данных break; case 2: //сообщение об некорректной длинне данных break; case default: //wtf? } либо, если default не предвидится, так: Код (PHP): //заготовленные сообщения $messages = [ 0 => 'ok', 1 => 'сообщение об некорректных данных', 2 => 'сообщение об некорректной длинне данных', 3 => 'сообщение o некорректном формате данных' ]; $msg = $messages[$result];//если default не нужен
За последние 20 лет я ни одного goto не написал. Обычно goto стоит там, где больше уместен break или return — как в твоем случае, Donald. Добавлено спустя 6 минут 51 секунду: А что касается исключений, то это не подходящая конструкция для управления потоком исполнения. Это "ахтунг!" и он должен означать именно ахтунг, а не выход из структурного блока.
p@R@dox 55RU значит пост не читал. Там вопрос именно по конкретной ситуации и по конкретному языку, который, мягко говоря, не без проблем в парадигме синтаксиса. YSandro Дело в том, что проверка полей может быть различная и прийдётся писать под каждое поле свою функцию или мудрить с параметрами одной. Первф вариант даже для процедурного программирования плох ибо заворачивает в функцию не повторяющийся код, а только кусок кода для сокрытия грамозкости + проблема вложенности условных ветвей не совсем решена. artoodetoo Веришь, я тоже не писал его лет 20. Но эти годы я не сталкивался с PHP 5.3. Писать всё в процедурном стиле не так просто как оказалось. ООП в PHP довольно сомнителен, но это отдельная тема. Кстати, break не сильно лучше goto N (имею ввиду во вложенных циклах), чисто для самоуспокоения, что он не goto.. Я же привёл пример, где обхожусь без goto, значит могу обойтись. Но у меня вопрос именно в том, насколько целесообразно заморать код вложенностью ветвлений и разбиением на процедуры (которыйе называют на PHP фенкциями), чем использовать goto?
Я тоже не пользую goto обычно, но не вижу в нём большой проблемы. Помню, на одном форуме по C была темка: один из участников сказал, что goto пользуются только школьники. Тогда другой участник привёл цитату из ядра Linux, и переписку, в которой Торвальдса пытались убедить переписать этот фрагмент без goto, а Линус доказывал, что с goto лучше читается.
А по мне так он все верно написал. Не использование ООП (собсно почему? в 5.3 есть всё для этого) не означает лапшу с бесконечной вложенностью. Что мешает организовать конвейер request-validation-action-respone и действовать в рамках него?
mkramer в линуксе много таких вставок. romach Верно или нет, пост он не читал, вот и написал не по теме топика. только мало, что из этого юзабельно для скриптового языка с динамической типизацией. Например, если следовать Java стилю, то надо каждый класс вьотдельный файл. Диски сервера на среднем проекте покажут такй LA, что мама не горюй. Прийдётся мутить с кешированием php, там могут авылезти другие грабли. ООП вобще подразумивает хранение состояния, а как его хранить, если скриптовый язык запросов-ответов "отработал и зыбыл". как он выглядит. Добавлено спустя 1 минуту 12 секунд: Да, да! Книжку цитировать - это не конкретный пример отрефакторить!
Тадам, на дворе 2015 год, на носу PHP7, все держат классы по файлам и сервера при этом не дохнут. Может стоит сначала разобраться в вопросе, а уже затем рассуждать о том что можно, а чего нельзя?
кэш и оптимизатор опкода ставят сразу поддержку romach скоро PHP 7 выйдет Donald лучше опиши задачу которую хочешь решить, если интересно другим способом решить задачу вложенность можно обойти рекурсией например
Я не понимаю, почему в моих словах находят то, чего я не утверждаю!? Где я говорю, что что-то нельзя (можно)!? Могу утверждать только одно на 100%, что классово-обьектный код будет работать не быстрее процедурного. Хотя большинство скажет, что мощности сейчас дешёвые и бла бла! Хотя на каждую мощность найдётся задача, которая с лихвой отжирает всю эту мощность... Никто не спешит даже на 6ю версию переходить! Куча старого кода будет тормозить переход с 5.х. Всё-равно странновато без всякой компиляции и линковки юзать в скриптовом языке обьекты. Я уже не говорю про то, что обьекты должны хранить состояние. На серверных скриптах это возможно, но не очень эфективно, особенно, если надо передавать от физического файла ку файлу обьект. Много разномастного софта написано на процедурном подходе. Но суть топика не об этом. Ещё раз подчеркну, реализовать без goto могу на большинстве языков, кроме синклер бейсика! Просто интересны способбы реализации, которые улучшат читаемость кода, в данном случае на php. denis01 ну примерную суть задачи я описал в начале топика. Могу дополнить только описанием некоторой сути: На странице интерфейс работы с записями БД в виде таблицы и элементрной формы из текстовых полей для добавления новой записи. Таблица - это тоже форма, которая умеет удалять сразу несколько записей чекбоксами и массово редактировать их сорстояние.. Отправляю POST на самого себя и делю этот пост на эти 2 случая: форма редактирования и форма добаления(через скрытое поле в одной из форм). Отсюда POST имеет 2 основных ветвления: редактирование и добавление данных. Поскольку добавление данных идёт в произвольной текстовой форме, то необходим минимальный контроль входных данных + вывод сообщений об успешном добалении данных или ошибке. Так же специфика php 5.3 генерит ошибку при обращении несуществующему ключу массива, что добавлает вложенности ветвлений. Начал выносить всё в процедуры, оказалось, что из-за индивидуальности проверки полей формы, надо либо наследоваться либо писать соврешенно разные процедуры под каждое поле формы..
Не представляю, в чём трудности, честно. Пишешь неповторяющийся код, потом в функции повторяющийся и т.д. Давай больше кода и примеров. Тебе практики нужно больше и чтения доков на оф. сайте. Особенно прочитай про 6-ю версию!!! ))
он для удобства, а не для быстроты. какие смелые заявления. два косяка уже. зацени Код (PHP): try { throwOnTrue(empty($_POST['member']), 'Укажите участника сообщества'); $comMember = Community::memberInfo($_POST['member']); throwOnBadArray($comMember, 'Участник не найден'); $member = Community::getMember($comMember['community']); throwOnFalse($member, 'Вы не являетесь участником сообщества'); throwOnFalse($member->right('alalala'), 'У вас нет права управления участниками'); throwOnTrue($comMember['id'] == $member->id, 'Вы не можете сами себя то да сё.'); throwOnFalse(Community::memberDeactivate($comMember['id']), 'Не удалось исключить участника. Внутренняя ошибка сервера.'); echo "OK"; } catch (Exception $ex) { echo "ERROR"; } Написано по мотивам, что называется, но суть передаёт. Никаких ветвлений. Клёво, да?
какую еще шестую???? ))))))))))))))) я не знаю кто там не спешит, я новый проект пишу на семерке ))) доволен как слон, есть сложности, но у меня запуск в конце ноября, выпустят релиз, ВСЕ будут писать на семерке, и переводить ВСЕ что есть на нее по сабжу, на бейсике все писали с GO TO, никто не помер ))) на пыхе пробовал в качестве эксперимента, но чет не пошло ))) тут и правда куча способов без него обойтись, но если честно я не вижу в этом ничего такого фуфуфу, ну написал с гоуто, ну пусть будет так, если тебе так понятно, просто и хорошо )
Я тоже не считаю, что фуфуфу, просто не нахожу случаев, когда бы он реально упрощал программу. Возможно в какой-то нано-отимизации он имеет смысл, хз. Но чтобы благодаря ему лучше читался код, я не представляю. Даже для do-while знаю хороший кейс, а вот для goto не знаю. ))) Покажите какой-нибудь "убийственный" пример с goto, пожалуйста. Чтобы выгода была очевидной. --------------------- Разберем тот пример, что в первом сообщении. Есть последовательность действий, которую нужно остановить при наступлении какого-то условия (любого из нескольких условий). В некоторых ЯП для такого кейса есть специальная конструкция BEGIN SEQUENCE - END, которую можно остановить оператором BREAK. Sequence это что-то типа цикла, который выполняется один раз. В PHP однократный цикл можно сделать так: do { } while(false) и выходим по break Переписываю фрагмент с goto из первого сообщения: Код (PHP): // begin sequence do { if ( isset($_POST['поле_данных_1']) ) { //сообщение об некорректных данных break; } if ( strlen($_POST['поле_данных_1']) > 2 ) { //сообщение об некорректной длинне данных break; } if ( preg_match('~\d~', $_POST['поле_данных_1']) !== 1 ) { //сообщение o некорректном формате данных break; } // что-то делаем с данными // ... // что-то делаем с данными } while (false); // end sequence То же самое можно было сделать с try-catch и выход по throw new Exception, но мне религия не позволяет так делать
без него НЕЛЬЗЯ обойтись. у ГОТО много имён: continue, break, for, while, switch, function, return ... может это когото удивит, но ЭТО ВСЁ по сути GOTO либо обвязка вокруг GOTO. например: встретили в коде break - видим что выполнение улетело кудато вниз, за цикл, начинаем перематывать, искать глазами конец цикла. а если: break 2; то вылетели аж из двух циклов. чем не goto? и ничего. пользуемся. читаемость программ не падает. всем всё нравится) в тех примитивных программах которые пишут для работы сайтов, действительно можно обойтись и без гото. а вот в коде с сложными алгоритмами использование гото МОЖЕТ иногда улучшить код, сделать его более оптимальным и т.д. примера приводить не буду, ибо алгоритмы бывают разные и использование гото тоже, гдето поможет а гдето навредит. нужно включать голову. гото - это истоки. это то из чего состоит цифровой мир. чтобы его использовать правильно - нужно быть опытным программистом. Он может очень помочь, а может и навредить, поэтому принято пугать им школоту, чтобы они не "отстрелили себе ногу". самое очевидное - контролируемый выход из вложенных конструкций типа for,while, switch... если их много и они вложены, то ИНОГДА бывает удобно сделать единую систему меток выхода или управления, и внутри циклов уже просто ходить по ним. ИНОГДА использование гото может сделать алгоритм более оптимальным, быстрым. но это не про PHP, а скорее про языки более низкого уровня. GOTO просто инструмент. ни хороший ни плохой. кто хочет и умеет тот пользуется, кто неумеет - ругает и боится его. это дело каждого.
Для этого есть break N — выход на следующий уровень вложенности Как я уже написал, я не считаю, что goto это прям кошмар. Но это расслабуха, нарушение полезных соглашений, стиля и для него должно быть веская причина. И лично я этой веской причины не нахожу. Добавлено спустя 4 минуты 38 секунд: Он не goto тем, что он понятен и предсказуем. Он не может вывести куда угодно, а только выходит из блока.
тоже самое. если блок большой особенно. что с break нужно искать куда именно ты попадаешь, искать закрывающую скобку в ворохе кода. что с goto, нужно искать метку, по её имени. что даже легче, ибо IDE эти метки подсветит красиво. goto ничем не страшнее. наговнокодить можно и с помощью других конструкций языка. Добавлено спустя 1 минуту 10 секунд: а если нужно вернуться в начало цикла?)
continue Слава макаронам, PHP достаточно далеко ушел от ассемблера. в нем есть почти всё для нормального программирования.
имхо, НАЧАЛО цикла и Следующая итерация - это разные вещи. я имел в виду ДО for(), например. Добавлено спустя 2 минуты 5 секунд: вот АДЪ, без GOTO: Код (PHP): $i = 0; while ($i++ < 5) { echo "Снаружи<br />\n"; while (1) { echo "В середине<br />\n"; while (1) { echo "Внутри<br />\n"; continue 3; } echo "Это никогда не будет выведено.<br />\n"; } echo "Это тоже.<br />\n"; }