Как конвертировать PHP-приложение на основе страниц в MVC? - PullRequest
11 голосов
/ 06 января 2009

В течение некоторого времени я боролся с тем, как именно перекодировать PHP-приложение на основе страницы, используя инфраструктуру MVC. Просто для справки, мне нужно перенести приложение в MVC, потому что мой босс делает меня. Во всяком случае, я сел и распечатал структуру каталогов. Затем я начал пытаться спланировать, как я могу преобразовать эти страницы в пары контроллер / действие. Некоторые вещи кажутся очень простыми. Например, у меня было несколько страниц, посвященных добавлению / редактированию / удалению пользователя. Это очень легко создать «пользовательский» контроллер и добавлять методы или действия для добавления / редактирования / удаления. У меня возникают проблемы, когда я решаю, когда на самом деле создать контроллер, а не делать что-то просто как действие, поскольку это не всегда так ясно. Например, контроллер входа в систему против пользователя / входа в систему или контроллер регистра в зависимости от пользователя / регистрации. Для меня, если объект может что-то сделать, имеет смысл быть действием, но это не всегда так ясно.

Другим примером может быть то, что у меня есть около 12 страниц форм, которые используются для создания «плана». В моей голове я бы подумал, что мне нужно создать «плановый» контроллер, и тогда каждый из старых страниц станет действием. Таким образом, у меня был бы один контроллер с 12 действиями (методами). Проблема для меня заключается в том, что хотя все эти 12 страниц являются формами ввода данных, которые в конечном итоге составляют этот «план», это все, что у них общего. Каждая из страниц использует разные таблицы в базе данных и не имеет ничего общего друг с другом. По сути, создав контроллер «плана», я просто использую его как механизм группировки; не обязательно использовать его, потому что они что-то связаны друг с другом. По крайней мере, в приведенном выше примере с «пользовательским» контроллером; каждое из этих действий использует одну и ту же «пользовательскую» таблицу, поэтому имеет смысл сгруппировать эти действия в один контроллер. Должен ли я сделать каждую из этих форм ввода данных собственным контроллером?

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

РЕДАКТИРОВАТЬ : Если я попытаюсь придерживаться одного контроллера для просмотра; Затем я буду сводить код для каждого запроса к минимуму. Это лучший способ?

РЕДАКТИРОВАТЬ : Судя по тому, что говорят все, кажется, что один контроллер на представление не в моих интересах. У меня все еще есть некоторые проблемы, потому что кажется, что контроллер может стать толстым в спешке, но это для другого обсуждения. У меня также есть некоторые вопросы, когда принимать решение использовать контроллер вместо действия. Хорошим примером будет стек overflow . В верхней части страницы у вас есть выбор «Вопросы», который, как мы можем предположить, приведет вас к контроллеру «Вопросы». Я говорю это потому, что с правой стороны вы можете выбрать «Задать вопрос», который URL указывает на «вопросы / задать». Это имеет смысл, если вы используете метод ask контроллера вопросов. Что меня смущает, так это то, что у вас есть опция «Без ответа» в меню. Похоже, это имеет контроллер для себя. Почему это не просто действие под контроллером вопросов, как в «вопросах / без ответа»? Вот где все становится мутным для меня.

Ответы [ 11 ]

4 голосов
/ 07 января 2009

, так как ваш босс доволен модным словом, скажите ему, чтобы он посмотрел "рефакторинг"

2 голосов
/ 08 января 2009

Какой смысл иметь один вид на контроллер?

Еще раз:

  1. Вы не загружаете больше кода, чем необходимо для запроса. Вы бы загрузили библиотеку, пакет, dll, которые вам не нужны? Конечно, нет. Так что не создавайте массивный файл контроллера, где только небольшая часть кода будет выполняться за запрос. Кроме того, меньшие файлы легче поддерживать imo, так же, как меньшие методы и модульный код.
  2. существует четкая связь 1: 1 между контроллером и представлением (особенно если они имеют одно и то же имя). Это соглашение. Это ясно и последовательно. Если я смотрю на шаблон представления, я точно знаю контроллер, который загружает его, основываясь только на имени файла. Здесь нет мышления. Нет решений. Никаких компромиссов.

Какая необходимость в разделении интересов, когда все соответствует паре?

Что нужно для разделения интересов? Если вы хотите сгруппировать связанные страницы (контроллеры / представления), объедините их в каталоги.

Я был бы более склонен написать контроллер, управляющий несколькими представлениями, которые так или иначе связаны между собой. Например, вышеупомянутое добавление / просмотр / редактирование пользователя. Вы хотели бы сохранить похожую функциональность вместе, а не искать во многих файлах нужный вам код. Также удобно, чтобы все методы были определены (для конкретного объекта) в одном месте. Облегчает техобслуживание.

Я собираюсь уважительно не согласиться. Если у меня есть одно представление, которое отвечает за добавление / просмотр / редактирование пользователя, то с соглашением 1: 1 я точно знаю, что отвечает контроллер. С другой стороны, если вы воспользуетесь вашим предложением о группировании аналогичных функций, если у меня есть контроллер менеджера и пользовательский контроллер, какой из них содержит добавление / просмотр / редактирование для менеджера? Пользователь или менеджер? Теперь вы должны думать или искать.

Я работал над проектом, используя PHP-фреймворк, который создавал отдельный файл для каждого «действия». Названный как «объект (действие)», и он стал НОЧНЫМ СОБЫТИЕМ.

Я не предлагаю этого.

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

Теперь я чувствую себя свистом. Я не знаю Django, и я предполагаю, что отдельные файлы являются необязательными, но я не могу сохранить файл с десятками тысяч строк.

Мой единственный совет - не пытайтесь организовать свой проект, основываясь на каком-то идеале MVC. Организуйте свой проект так, как он имеет смысл для вас и вашего домена.

Нет, нет, нет. Это очень опасный совет. Шаблоны проектирования, соглашения о кодировании и структуры были разработаны с целью - лучшие практики и согласованность. Только гуру должен выходить за рамки условностей и только если он / она работает один. Даже в рамках фреймворка я постоянно стремлюсь к большей согласованности, чтобы мне не приходилось думать при написании или поддержке кода.

2 голосов
/ 07 января 2009

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

ОБНОВЛЕНИЕ: Если я попытаюсь придерживаться одного контроллера для каждого просмотра ... Тогда я буду сводить код для каждого запроса к минимуму, но лучше ли это?

Если я правильно вас понимаю, каждый контроллер выдаст одну страницу. Это может быть действительно плохой идеей, которую я испытал из первых рук в должности технического обслуживания. Если у вас есть контент, который не совсем соответствует парадигмам ОО, поместите его в категорию: пресс-релизы, одноразовые, информационные и т. Д. И вставьте их в контроллер, который обслуживает только эти представления или, что еще лучше, количество контроллеров на категории, чтобы оставить более мелкозернистый контроль.

Фреймворк "MVC", с которым я имел дело, позволил быстро увидеть один контроллер, который превратился в запутанный беспорядок с множеством хаков и спагетти-кода.

У меня есть около 12 страниц форм, которые используются для создания «плана».

Мне приходилось делать что-то похожее, и, как бы глупо это ни казалось, лучше всего иметь контроллер формы планирования. Да, есть несколько таблиц для подачи, но вы можете делать простые вещи, такие как $ _SESSION ['plannerController'] ['subject | action'] [key] [value], чтобы контролировать каждую часть формы в целом. Наличие каждого метода, обрабатывающего часть многостраничной формы, также может быть полезным (например, что если ваш начальник скажет, что им нужно только 6 из 12 страниц, или что, если часть 7 станет действительно сложной и нуждается в таких вещах, как автозаполнение ajax).

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

Мне обычно нравится один класс, одна целевая парадигма, но иногда просто не имеет смысла пытаться это делать. Есть случаи, когда это ясно, прямо из учебника OO и в других случаях академический BS может пойти в ад. Вы собираетесь находить вещи, которые не соответствуют форме OO, поэтому вы можете сделать шаг назад и попытаться объединить вещи в общие категории.

1 голос
/ 08 января 2009

У меня также есть некоторые проблемы, связанные с принятием решения использовать контроллер вместо действия. Хорошим примером будет этот веб-сайт stackoverflow. В верхней части страницы у вас есть выбор «Вопросы», который, как мы можем предположить, приведет вас к контроллеру «Вопросы». Я говорю это, потому что с правой стороны вы можете выбрать «Задать вопрос», который URL указывает на «вопросы / задать». Так что имеет смысл использовать метод ask контроллера вопросов.

Ну, мы не знаем, является ли «спросить» действием контроллера «вопросов». Этот сайт может перенаправлять URL «questions / ask» на другой контроллер, или «ask» может быть контроллером в каталоге «questions». Также, если вы откроете страницу «вопросы / вопросы», вы заметите, что форма публикуется в разделе «вопросы / вопросы / публикации». Теперь «post» может быть параметром для метода действия «ask», но я думаю, это метод «post» действия контроллера «ask».

Кто знает. Но учтите: для страницы «Вопросы» потребуется в несколько раз больше кода, чем для страницы «Задать вопрос». Имеет ли смысл загружать код страницы «Вопросы» при загрузке страницы «Задать вопрос». Я бы подумал, что ребята из stackoverflow будут умнее этого.

Но что меня смущает, так это то, что у вас есть опция «Без ответа» в меню. Похоже, это имеет контроллер для себя. Почему бы не просто действие под контроллером вопросов? Как в "вопросы / без ответа"? Вот где все становится мутным для меня.

Еще одна причина, по которой я считаю, что страница «Задать вопрос» имеет свой собственный контроллер. Страница «Вопросы» имеет гораздо больше общего со страницей «Без ответа».

1 голос
/ 08 января 2009

Я пережил нечто подобное в прошлом году. Я преобразовал свои в основном статические страницы веб-сайта PHP для использования Kohana PHP Framework . Я сделал каждый раздел веб-сайта контроллером, с представлениями для отдельных страниц. Основные просмотры страницы включали другие представления для верхнего и нижнего колонтитула. Некоторые из представлений, например, для статей, могут использоваться разными контроллерами. В результате был создан сайт MVC с теми же URL-адресами страниц, что и у исходного веб-сайта.

РЕДАКТИРОВАТЬ: URL-адреса в формате аргументов / controller / method? Например, на моем сайте URL для /computer/article.php?id=# использует функцию article в контроллере computer . Контроллер computer , в свою очередь, использует модель article для загрузки данных в представление article с вложенными абзацами представления. Это также показывает, что, хотя в предыдущей версии сайта были имена страниц с расширением .php в URL, это все равно можно преобразовать в метод класса контроллера, и тот же URL работает в версии сайта на основе MVC. Это должно дать вам представление о том, как Kohana может работать на вашем сайте.

1 голос
/ 07 января 2009

Какой смысл иметь один вид на контроллер? Какая необходимость в разделении интересов, когда все соответствует паре?

Я бы более склонен написать контроллер, который управляет несколькими представлениями, которые так или иначе связаны между собой. Например, вышеупомянутое добавление / просмотр / редактирование пользователя. Вы хотели бы сохранить похожую функциональность вместе, а не искать во многих файлах нужный вам код. Также удобно, чтобы все методы были определены (для конкретного объекта) в одном месте. Облегчает обслуживание.

Я работал над проектом, используя PHP-фреймворк, который создавал отдельный файл для каждого «действия». Названный как «объект (действие)», и он стал НОЧНЫМ СОБЫТИЕМ.

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

Мой единственный совет - не пытайтесь организовать свой проект на основе какого-то идеала MVC. Организуйте свой проект так, как он имеет смысл для вас и вашего домена. MVC было предложено ограничить сложность, а не увеличить ее.

Для вашего примера плана я бы превратил это в контроллер. www.example.com/plan/1 .. / plan / 2 и т. д. Это имеет смысл, потому что действия логически сгруппированы вместе, чтобы сформировать некоторую задачу.

Контроллер, по моему мнению, должен использоваться для управления задачей или объектом. Его методы должны быть конкретными действиями, необходимыми для выполнения этой задачи или изменения / использования объекта.

1 голос
/ 06 января 2009

Делая такой шаг, вы не просто меняете реализацию конкретного сайта, а скорее меняете его восприятие. В любом случае, вам придется сделать немало перекодировки, но у вас есть преимущество в понимании концепции и наличии опыта в том, как это сделать.

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

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

0 голосов
/ 13 мая 2009

Если у вас есть какие-то тесты под рукой, охватывающие большинство (все?) Функциональных возможностей вашего приложения.

  1. Изложите действительно базовую структуру того, как будет выглядеть ваша C-часть.
  2. Реализуйте эту структуру, игнорируя M и V, более или менее просто копируя фрагменты кода из ваших ориентированных на страницы файлов в ваши контроллеры
  3. Проверьте, что все работает как положено
  4. Пройдите через каждый контроллер, извлеките буквы "M" и "V". «М» может быть просто активной записью (я знаю, это не настоящая модель) или шлюзом таблицы строк или чем-то, что достаточно быстро реализуется. Контроллер теперь должен становиться все тоньше и тоньше
  5. Проверить, что все работает как положено
  6. Теперь, когда вы знаете все о своем приложении, выполните рефакторинг еще раз, чтобы извлечь модель домена, если это применимо. В некоторых случаях это может быть просто пустой тратой времени (только для CRUD-приложений)
  7. Проверьте, что все по-прежнему работает, как ожидалось.
0 голосов
/ 13 мая 2009

Вся эта концепция стала более понятной для меня благодаря серии из трех сообщений в блоге Nemetral это объясняет шаблон по мере его развития из традиционного сценария веб-страницы и, следовательно, по мере того, как логика PHP становится отдельной от логики представления, то есть с точки зрения MVC, то, как модель становится отдельной от представления. По Nemetral:

  1. Первый шаг - переместить весь код PHP, который до сих пор был связан с тегами HTML, в начало страницы.
  2. Второй шаг - переместить все теги HTML в отдельный файл и получить к нему доступ через PHP include. Поэтому, когда делается запрос, он направляется в код PHP (контроллер и модель), а затем этот код запрашивает теги HTML или представление (представление).

Я пишу больше об этом в своей диссертации: http://kreus -cms.com / kreus / pages / writing_work

0 голосов
/ 08 января 2009

Если я правильно вас понимаю, каждый контроллер выдаст одну страницу. Это может быть действительно плохой идеей, которую я испытал на собственном опыте в должности технического обслуживания.

Фреймворк "MVC", с которым я имел дело, позволил быстро просмотреть один контроллер и превратился в запутанный беспорядок со множеством хаков и спагетти-кода.

Это из-за фреймворка, разработчика или обоих? Как это было трудно поддерживать? Какие хаки были задействованы и почему?

Мне хорошо подходит 1 контроллер к 1 в средах php MVC Zend, CodeIgniter и Kohana. В ASP.NET, хотя и не MVC, 1 веб-форма / представление сопоставляется с 1 кодом позади файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...