Гигантская цепочка elseif, гигантский переключатель или крошечный переключатель с функциями?


У меня есть PHP-файл из 9000 строк, который состоит примерно из 30 отдельных областей, к которым можно перейти с помощью переменных $_POST. Так что один из них может быть...

elseif (isset($_POST['view_user']) 
     || isset($_POST['edit_user']) 
     || isset($_POST['process_user_status']))

... и так далее. У меня, вероятно, есть около 75 точек входа в эти тридцать областей, все они обрабатываются длинными цепочками иссетов, подобными приведенным выше.

Я подумывал о том, чтобы сменить это на что-то более разумное. Идеи, которые я придумал до сих пор:

1) Сведите сообщения к логическому значению и используйте его в другом случае цепь. Таким образом, вышесказанное будет сведено к elseif ($area_user), при этом $area_user будет установлено в true, если был установлен какой-либо из $_POST выше. Но на самом деле это не решает проблему сложности.

2) Используйте варианты вместо elseif. Таким образом, вышесказанное стало бы...

case (isset($_POST['view_user'])):
case (isset($_POST['edit_user'])):
case (isset($_POST['process_user_status'])):
    do stuff;
    break;

Но, опять же, хотя он удаляет синтаксис elseif, он просто заменяет его чем-то, что, хотя и немного более управляемо, все же может скрывать истинную проблему.

3) Используйте функции. Итак, в верхней части страницы у меня есть аналогичная инструкция switch, но вместо того, чтобы находиться в середине страницы, переходящей непосредственно в область сценария, она вызывает функцию, поэтому вместо "делать что-то" она может вызывать UserArea($_POST['whatever']). Это имеет то преимущество, что все переменные $_POST перемещаются за пределы основной части скрипта и концентрируются в вызовах навигации и функций. Однако для этого потребуется множество глобальных объявлений функций, которые в настоящее время мне не нужно делать, потому что ветви elseif находятся в глобальном область применения.

4) Полностью рефакторинг с полным разделением MVC, шаблонами и т.д. С удовольствием, но в данный момент это не вариант. Просто радуйтесь, что я отделил модель, но пока представление и контроллер должны сосуществовать.

Пока я пишу это, я все больше и больше убеждаю себя в 3, но я хотел посмотреть, что вы, добрые люди, думаете. Какой должна быть наилучшая практическая навигация в подобной ситуации?

Author: Andrew, 2011-02-21

1 answers

Еще один вариант для вас: Словарь функций обработчика.

Поместите все ваши потенциальные ключи $_POST ('view_user' и т. Д.) В ассоциативный массив, указывающий на функцию (имя), которая их обрабатывает. Затем вместо цепочки ifelse выполните итерацию по фактическим ключам $_POST, пока не найдете совпадение в массиве и не вызовете соответствующую функцию.

Теперь вы можете без проблем перемещать свои функции обработчика в другие файлы, хотя вам может потребоваться добавить некоторые параметры для этого вызова динамической функции. Этот вид отправки используется большинством платформ MVC (для шаблонов в пути, а не для данных формы или строки запроса).

// Untested, but something like this
$handlers = array(
  'view_user' => 'UserArea',
  'edit_user' => 'UserArea',
  'view_document' => 'DocManagement', // for example
  // etc...
);
foreach ($_POST as $key => $value) {
  if(array_key_exists($key, $handlers)){
    call_user_func($handlers[$key]);
  }
}
 2
Author: Jesse Millikan, 2015-01-24 09:30:46