Гуру, я не знаю что такое MVC в PHP, хоть и считаю себя опытным программистом. Объясните наконец!

Проверенные VDS на SSD в Европе от $4 и России: Датацентр №1 от 199руб

Тема в разделе "Вопросы по теории программирования", создана пользователем Активист, 4 мар 2011.

  1. Активист

    Активист Активист Команда форума

    Сообщения:
    2.296
    Ваш город:
    Irkutsk, Russia
    Address:
    Irkutsk, Russia
    Country:
    Location on Map:
    Сабж.

    Вопрос к гуру без флада.

    Надоело читать и видеть какие-то старнные коды, включая дикие фреймворки, в которых фигурируют слова controller, model, view, actions в PHP, а я их действительно считаю странными и о людях применяющих их - могу предположить - они не понимают его сути и такое ООП - не является ООП и они заблуждаются.

    Что такое MVC - это паттерн GUI приложений, которые работают сколь угодно долго, а не как скриптовый язык, живущий доли секунд.

    Controller - своего рода контроллер IRQ, он отслеживает внешние факторы во время жизни программы, как это применимо к PHP - не понимаю. В PHP не может быть контроллера. Контроллером в нашем случае является сам интерпретатор. Контроллер отслеживает запросы изменения состояния и случае чего, изменяет свойства отображения, но объектв в PHP скрипте не можгут поменять состояние и передать его отображению, т.к., отображение в PHP не имеет динамических свойств.

    Model - это логика, расчеты, действия, которые непосредственно выполняется при изменении состояния, т.е. в случае PHP - это само приложение.

    View - его задача отрисовывает визуальную часть, имеющих точки входа от контроллера для смены своего состояния, но - нет контроллера (см. выше), а также, нет ни каких внешних факторов меняющихся с течением времени, а значит то что будет отрисовано - не измениться.

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

    Таким образом, я утверждаю - в PHP нет MVC. А так же - MVC это не стиль кодинга, это объекты, но с появлением этого паттерна в PHP я ниразу в жизни не видел что бы кто-то хоть как-то сделал из разбросанных кусков кода с названием controller, model, view по файлам объект!

    И еще - почему сейчас все вакансии требуют знания MVC если его нет в PHP, что это за такое модное название? У меня колосальный опыт и я понимаю что такое MVC, но я не понимаю как его можно применять в PHP?
     
  2. fixxxer

    fixxxer К.О. Партнер клуба

    Сообщения:
    12.462
    Ваш город:
    Moscow, Russia
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    Ну, да, то, что все называют MVC в вебдеве, это не MVC а непойми что. :)

    В классическом виде MVC, например, можно изобразить на вебсокетах, View будет в браузере, Model на сервере, а Controller - транспорт/управление/роутинг, взаимодействие с обеих сторон.
     
  3. igortik

    igortik Новичок

    Сообщения:
    510
    Ваш город:
    Киев
    Address:
    Kiev, Ukraine
    Country:
    Location on Map:
    Я бы сказал, что это ход мышления при написании кода, т.е. постановка задач на уровне распределения все на кусочки, субзадачи, которые самостоятельно выполняют свои функции, результат которых влияет на поведение друг-друга.

    Простейший пример:

    1. Разобрали входящий ЧПУ-подобный урл, определили активный контроллер (скрипт, на который будут отправлены полученные данные из запроса)
    2. Контроллер выполняет логические действия, оперируя этими данными, например, получив ID новости, он вызывает метод (на примере класса), который передает этот ID модели и "говорит" - дай мне все, что касается конкретной новости $this->getArticle($id)
    3. Модель, получив $id отдает, например, массив данных - заголовок, дату, текст
    4. Далее контроллер задает значение переменной для view $this->view->articles(результат выполнения $this->getArticle($id));

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

    Зачем это нужно?

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

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

    А можно в системе обходиться и вовсе без термина "модуль", а считать, что существуют лишь контроллеры и модели + вывод.
    Модуль, в моем случае, для меня удобен для восприятия, т.к. у меня в одной папке лежат и js и css + прочая статика (шаблоны форм и т.д.), что помогает группировать информацию, ну и, конечно же, контроллеры и модели.

    Что такое ТТУК.

    Толстый тупой уродливый контроллер.
    Так принято называть контроллеры, которые выполняют еще и роль модели.

    Я использовал такой метод ранее и пока жив здоров.
    Но, соглашусь, что разделение этого файла на отдельно контроллер и модель дают, как минимум, лучшую читабельность кода, не заморачивая алгоритмами самого контроллера, а когда модуль будет строиться из 10-20 действий разного характера, то разделение по принципу MVC будет очень уместным, есть контроллер получения новости по ID - есть модель, которая хлопочет о получении массива данных новости. При возникновении ошибок ты быстро находишь одно либо другое и правишь код.
     
  4. Mols

    Mols Новичок

    Сообщения:
    623
    Ваш город:
    Донецк
    Address:
    Donetsk, Ukraine
    Country:
    Location on Map:
    Мда ...
    MVC вообще никаким боком не касается ООП
    http://ru.wikipedia.org/wiki/MVC
     
  5. igortik

    igortik Новичок

    Сообщения:
    510
    Ваш город:
    Киев
    Address:
    Kiev, Ukraine
    Country:
    Location on Map:
    Потому, что это модно, потому, что без знания Зенд Фреймворк ты не программист, потому, что, если ты не работал в команде - ты тоже не программист и еще ряд всякой ахинеи.
    Я собрал уже 60+ сайтов за жизнь, которые кормят меня профитом от рекламы, все писал сам, пусть на говно цмс своего производства, но они работают и решают конкретные задачи, код выдержан корректно, за исключением первого десятка проектов, где хтмл пересекался с пхп.

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

    Потому, не советую заморачиваться на счет всех деталей мира "вебдев", взгляни за окно, скоро весна, в жизни есть еще масса интересных вещей :)
     
    Pronin1986 нравится это.
  6. fixxxer

    fixxxer К.О. Партнер клуба

    Сообщения:
    12.462
    Ваш город:
    Moscow, Russia
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    "ТТУК" это как раз следствие притягивания за уши MVC. Ну как бы "M" (тут все ясно) и "V" (= Renderer+Template) очевидны - потому и взят вроде бы подходящий паттерн. Но вот с "C" проблемы.
     
    Активист нравится это.
  7. Духовность™

    Духовность™ Продвинутый новичок

    Сообщения:
    5.004
    Address:
    Vidnoye, Russia
    Country:
    Location on Map:
    ТТУК - это некорректная реализация MVC, а не следствие "притягивания за уши".

    Активист
    Вау, ты крут, ты показал, что отлично понимаешь роль MVC в гуишной среде. В "в PHP нет MVC". Отлично, я предлагаю тогда ввести новую терминологию, при которой мы могли бы четко описать слои системы. А слои, как igortik сказал, состоят из трёх основных типов:

    1. Запускаемый сценарий
    2. Объекты домена и логика домена
    3. Шаблонизация

    Как ты их не назови, MVC или ещё как, суть останется та жа:
    - Это и есть MVC для PHP. Разделение кода на три основные части. Всё остальное - демагогия остроконечников с тупоконечниками и фап на недосягаемые нетленные идеалы.

    У меня контроллер MVC (в моем понимании) выглядит так:

    PHP:
    class Module_Advert_Controller_BackendMain extends Module_Advert_Controller_BackendCommon
    {
        public function 
    run()
        {
            
    // какая-то инициализация....
            
    parent::common();
            
    parent::init();

            
    // проверка доступа - задача контроллера 
            
    if (!$this->checkAccess())
            {
                return 
    $this->createNotification()
                            ->
    setMessage('forbidden_access')
                            ->
    setType('alert')
                            ->
    setRedirectUrl('/admin/')
                            ->
    run();
            }

            
    // Module_Advert_Service_List - класс, получающий на основании данных из Request
            // список записей (в данном случае - список объявлений) + данные для "отстраничивателя"
            
    $list = new Module_Advert_Service_List
            
    (
                
    $this->getRequest(), $this->getMapper('Advert/Advert'), new Base_Navigation(10100)
            );

            
    // отдаем данные во View (шаблонизатор)
            
    $this->getView()->adverts $list->getList();
            
    $this->getView()->navigation $list->getNavigation();

            
    $this->getView()->field_name $list->getSortFieldName();
            
    $this->getView()->sort_order $list->getSortOrder();

            
    $this->getView()->id_category $this->getRequest()->getRequest('id_category');
            
    $this->getView()->id_user $this->getRequest()->getRequest('id_user');

            
    // Отдали главному контроллеру приложения (Base Application)
            
    return $this->getView();
        }
    }
    А недавно данный код был ТТУК-ом и исполнял роль самого контроллера и логики сервиса модели:

    PHP:
    class Module_Advert_Controller_BackendMain extends Module_Advert_Controller_BackendCommon
    {
        public function 
    run()
        {
            
    parent::common();

            if (!
    $this->checkAccess())
            {
                return 
    $this->createNotification()
                            ->
    setMessage('forbidden_access')
                            ->
    setType('alert')
                            ->
    setRedirectUrl('/admin/')
                            ->
    run();
            }

            
    $this->init();

            
    $sort_cols_values = array
            (
                
    'id' => 'advert.id',
                
    'header' => 'advert_header',
                
    'category' => 'category.category_name',
                
    'active' => 'advert_active',
                
    'user_name' => 'user.user_first_name',
                
    'view_count' => 'advert_view_count',
            );

            
    $real_order_field_name = ($this->getRequest()->getRequest('field_name') &&
                                      isset(
    $sort_cols_values[$this->getRequest()->getRequest('field_name')]))
                                     ? 
    $sort_cols_values[$this->getRequest()->getRequest('field_name')]
                                     : 
    $sort_cols_values['id'];

            
    $real_order_type = ($this->getRequest()->getRequest('sort_order') &&
                                
    in_array($this->getRequest()->getRequest('sort_order'), array('ASC''DESC')))
                               ? 
    $this->getRequest()->getRequest('sort_order')
                               : 
    'DESC';

            
    $sql_where_string $sql_where_args = array();

            if (
    $this->getRequest()->getRequest('id_category') &&
                
    Base_Numeric::is_decimal($this->getRequest()->getRequest('id_category')))
            {
                
    $sql_where_string[] = '`advert`.`advert_category` = ?i';
                
    $sql_where_args[] = $this->getRequest()->getRequest('id_category');
            }

            if (
    $this->getRequest()->getRequest('id_user') &&
                
    Base_Numeric::is_decimal($this->getRequest()->getRequest('id_user')))
            {
                
    $sql_where_string[] = '`advert`.`advert_id_user` = ?i';
                
    $sql_where_args[] = $this->getRequest()->getRequest('id_user');
            }

            
    $navigation = new Base_Navigation(10100);
            
    $start_limit $navigation->getStartLimit();
            
    $stop_limit $navigation->getStopLimit();

            
    $params = array
            (
                
    'where' => ($sql_where_string && $sql_where_args)
                           ? array(
    implode(' AND '$sql_where_string) => $sql_where_args)
                           : 
    '',
                
    'order' => array($real_order_field_name => $real_order_type),
                
    'limit' => array('start' => $start_limit'stop' => $stop_limit),
            );

            
    $this->getView()->adverts $this->getMapper('Advert/Advert')->findListForBackend($params);

            
    $navigation->setCount($this->getMapper('Advert/Advert')->getFoundRows());

            
    $this->getView()->navigation $navigation;

            
    $this->getView()->field_name $this->getRequest()->getRequest('field_name') ?: 'id';
            
    $this->getView()->sort_order $real_order_type;
            
    $this->getView()->id_category $this->getRequest()->getRequest('id_category');
            
    $this->getView()->id_user $this->getRequest()->getRequest('id_user');

            return 
    $this->getView();
        }
    }
     
    igortik нравится это.
  8. Активист

    Активист Активист Команда форума

    Сообщения:
    2.296
    Ваш город:
    Irkutsk, Russia
    Address:
    Irkutsk, Russia
    Country:
    Location on Map:
    2all... У меня есть что сказать, но сегодня много работы, три выходных близятся, план...

    Духовность™
    Твой код удобно читать. там есть систематизация, но простой вопрос: какие объекты контролирует твой контроллер? Налицо обычный загрузчик модуля, контроль объектов я там не вижу (налицо то, что скзал фиксер), да, как сказал igortik
    Т.е.,
    - распределения все на кусочки (стиль коддинга, а не ООП)
    - субзадачи, которые самостоятельно выполняют свои функции, результат которых влияет на поведение друг-друга. (Epic fail!)

    Налицо - подмена понятий.
     
  9. Активист

    Активист Активист Команда форума

    Сообщения:
    2.296
    Ваш город:
    Irkutsk, Russia
    Address:
    Irkutsk, Russia
    Country:
    Location on Map:
    Духовность™
    И небольшой офф - как ты настраиваешь IDE (PHPDoc), что бы тот на
    $this->getMapper('Advert/Advert')->
    выдавал доступные свойства и методы объекта ?
     
  10. craz

    craz Нестандартное звание

    Сообщения:
    2.788
    Ваш город:
    Samara, Russia
    Address:
    Samara, Russia
    Country:
    Location on Map:
    вопрос глуповат... конечно же не потому, что автор глуп, просто понимаете все в жизни относительно, можно сказать что и ООП не существует, ведь нет же не каких реальных объектов. Так и MVC - не забывайте что это всего лишь паттерн проектирования
    представим простой псевдокод

    PHP:
    class Db{//реализация}
    class ModelPage extends Db{
     public function 
    getPageById(){
    //реализация
     
    }
    }
    $modelPage = new ModelPage;
    if(
    $this->url == "index"){
    $page =  $modelPage->getPageById($this->getParam['id']);
    echo 
    "<div class='content'>".$page."</div>";
    }
    Это понятное дело не MVC, в MVC превращается в полночь, когда садишься все это переписать и отделить логику от представления. Не более того
     
  11. Духовность™

    Духовность™ Продвинутый новичок

    Сообщения:
    5.004
    Address:
    Vidnoye, Russia
    Country:
    Location on Map:
    а никак. Я не умею с IDE работать, поэтому мне он ничего не выдает :D

    MVC уже не тот :)
    Я же говорю - для меня термин MVC - это то, что я делаю в своем коде и мне как-то по барабану тот абстрактный и недосягаемый идеальный MVC, о котором ты говоришь. Дело в том, что так пишут очень многие и я склонен полагать, что именно такой подход в PHP является, по меньшей мере, одним из возможно правильных. В моём коде я имею четкое разграничение на:
    - контроллер (glue layer), задача которого лишь быть своеобразной "командой", запускающей модели и НИЧЕГО не знающего о логике домена.
    - сервиса "Module_Advert_Service_List" содержащую логику домена (в данном случае выборка объектов типа Adverts) и передача результата во View. Сервис инкапсулирует множество доменных объектов и логику их работы.
    - представления, которым является php-pure шаблонизатор на ob_* функциях, PHP и stdout.

    Всё согласно правилу:
     
  12. Активист

    Активист Активист Команда форума

    Сообщения:
    2.296
    Ваш город:
    Irkutsk, Russia
    Address:
    Irkutsk, Russia
    Country:
    Location on Map:
    > а никак. Я не умею с IDE работать
    Т.е., все на память?)

    Ну дк вывод - MVC в PHP это не ооп, а стиль программирования?!
     
  13. craz

    craz Нестандартное звание

    Сообщения:
    2.788
    Ваш город:
    Samara, Russia
    Address:
    Samara, Russia
    Country:
    Location on Map:
    ну почему не ооп то? объекты же имеются? есть контролер вид модель.
     
  14. Активист

    Активист Активист Команда форума

    Сообщения:
    2.296
    Ваш город:
    Irkutsk, Russia
    Address:
    Irkutsk, Russia
    Country:
    Location on Map:
    Обьект и класс - разные вещи))

    Предлагаю разделить понятия КОК и ООП.
    1. Классо-Ориентированный-Коддинг
    2. Объектно-Ориентированное-Программирование
     
  15. craz

    craz Нестандартное звание

    Сообщения:
    2.788
    Ваш город:
    Samara, Russia
    Address:
    Samara, Russia
    Country:
    Location on Map:
    ну тут они не разные... ВИД - это объект программы, не бизнес-логики, но программы. И модель сама по себе объект, и контроллер тож.
    Кстати вот "класcическое" MVC в Z, когда данные приходят в вид такое ощущение что вид нефига не объект нету никакого инстанцирования, но в тоже время там просто это все спрятано. и можно получить этот объект

    var_dump($this->view);
     
  16. Духовность™

    Духовность™ Продвинутый новичок

    Сообщения:
    5.004
    Address:
    Vidnoye, Russia
    Country:
    Location on Map:
    что значит не ООП? По факту ООП начинается тогда, когда хотя бы два объекта могут между собой иметь зависимости, взаимодействовать. Я вообще не понял, причем тут ООП и почему "MVC в PHP это не ооп"..

    MVC это концепция, а не паттерн ООП. MVC можно построить и на функциях, просто это будет немного неуклюже, но суть будет та жа.
     
    Sokil.Dmytro нравится это.
  17. craz

    craz Нестандартное звание

    Сообщения:
    2.788
    Ваш город:
    Samara, Russia
    Address:
    Samara, Russia
    Country:
    Location on Map:
    пример MVC на php на фукнциях?

    Как я считаю, без ООП MVC не напишешь. некуда примешивать будет результаты работы "модели"- да и модель будет отсутствовать, потому что модель это класс.
     
  18. Духовность™

    Духовность™ Продвинутый новичок

    Сообщения:
    5.004
    Address:
    Vidnoye, Russia
    Country:
    Location on Map:
    Я согласен, что MVC на функциях - это Ппц. Но
    Модель - это не класс. Модель - это логика программы, не завязанная на представлении и существующая как некое ядро, описывающее некую сущность в программе. Хочешь пример модели на функциях? Пожалуйста:
    PHP:
    $user = array('name' => 'Craz''age' => '26''status' => 'детский сад');

    function 
    printUser(array $user)
    {
        
    print_r($user);
    }

    function 
    getUserName(array $user)
    {
        return 
    $user['name'];
    }

    function 
    saveUser(array $user)
    {
        
    // insert into users set ..... 
    }
    Вот эта совокупность логики предметной области и массива с данными - это модель.
     
    Adelf нравится это.
  19. craz

    craz Нестандартное звание

    Сообщения:
    2.788
    Ваш город:
    Samara, Russia
    Address:
    Samara, Russia
    Country:
    Location on Map:
    сугубо имхо это не модель... нет инкапсуляции нельзя от наследоваться. много минусов.
     
  20. Adelf

    Adelf Laravel&PhpStorm Команда форума

    Сообщения:
    3.128
    Ваш город:
    Казань
    Address:
    Kazan, Russia
    Country:
    Location on Map:
    Активист
    Я понимаю некоторое твоё недоумение, но причем здесь ООП я тоже не понимаю.
    MVC в общем виде - это не ООП-паттерн.

    З.Ы. Для десктопных систем ,имхо более подходящ MVP. Вот его как раз необъектным представить сложно. Там интерфейсы, их реализации...