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

Активист

Активист
Команда форума
Сабж.

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

Надоело читать и видеть какие-то старнные коды, включая дикие фреймворки, в которых фигурируют слова 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?
 

fixxxer

К.О.
Партнер клуба
Ну, да, то, что все называют MVC в вебдеве, это не MVC а непойми что. :)

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

igortik

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

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

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 - есть модель, которая хлопочет о получении массива данных новости. При возникновении ошибок ты быстро находишь одно либо другое и правишь код.
 

Mols

Новичок
Мда ...
MVC вообще никаким боком не касается ООП
Model-view-controller (MVC, «Модель-представление-поведение», «Модель-представление-контроллер») — архитектура программного обеспечения, в которой модель данных приложения, пользовательский интерфейс и управляющая логика разделены на три отдельных компонента, так, что модификация одного из компонентов оказывает минимальное воздействие на другие компоненты.
http://ru.wikipedia.org/wiki/MVC
 

igortik

Новичок
И еще - почему сейчас все вакансии требуют знания MVC если его нет в PHP, что это за такое модное название? У меня колосальный опыт и я понимаю что такое MVC, но я не понимаю как его можно применять в PHP?
Потому, что это модно, потому, что без знания Зенд Фреймворк ты не программист, потому, что, если ты не работал в команде - ты тоже не программист и еще ряд всякой ахинеи.
Я собрал уже 60+ сайтов за жизнь, которые кормят меня профитом от рекламы, все писал сам, пусть на говно цмс своего производства, но они работают и решают конкретные задачи, код выдержан корректно, за исключением первого десятка проектов, где хтмл пересекался с пхп.

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

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

fixxxer

К.О.
Партнер клуба
"ТТУК" это как раз следствие притягивания за уши MVC. Ну как бы "M" (тут все ясно) и "V" (= Renderer+Template) очевидны - потому и взят вроде бы подходящий паттерн. Но вот с "C" проблемы.
 

Духовность™

Продвинутый новичок
"ТТУК" это как раз следствие притягивания за уши MVC
ТТУК - это некорректная реализация MVC, а не следствие "притягивания за уши".

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

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

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

        // отдаем данные во 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(10, 100);
        $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();
    }
}
 

Активист

Активист
Команда форума
2all... У меня есть что сказать, но сегодня много работы, три выходных близятся, план...

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

Налицо - подмена понятий.
 

Активист

Активист
Команда форума
Духовность™
И небольшой офф - как ты настраиваешь IDE (PHPDoc), что бы тот на
$this->getMapper('Advert/Advert')->
выдавал доступные свойства и методы объекта ?
 

craz

Нестандартное звание
вопрос глуповат... конечно же не потому, что автор глуп, просто понимаете все в жизни относительно, можно сказать что и ООП не существует, ведь нет же не каких реальных объектов. Так и 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 превращается в полночь, когда садишься все это переписать и отделить логику от представления. Не более того
 

Духовность™

Продвинутый новичок
И небольшой офф - как ты настраиваешь IDE (PHPDoc), что бы тот на
$this->getMapper('Advert/Advert')->
выдавал доступные свойства и методы объекта ?
а никак. Я не умею с IDE работать, поэтому мне он ничего не выдает :D

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

Всё согласно правилу:
* Модель (Model). Модель предоставляет данные (обычно для View), а также реагирует на запросы (обычно от контроллера), изменяя своё состояние.
* Представление (View). Отвечает за отображение информации (пользовательский интерфейс).
* Поведение (Controller). Интерпретирует данные, введённые пользователем, и информирует модель и представление о необходимости соответствующей реакции.
 

Активист

Активист
Команда форума
> а никак. Я не умею с IDE работать
Т.е., все на память?)

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

Активист

Активист
Команда форума
Обьект и класс - разные вещи))

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

craz

Нестандартное звание
Обьект и класс - разные вещи))
ну тут они не разные... ВИД - это объект программы, не бизнес-логики, но программы. И модель сама по себе объект, и контроллер тож.
Кстати вот "класcическое" MVC в Z, когда данные приходят в вид такое ощущение что вид нефига не объект нету никакого инстанцирования, но в тоже время там просто это все спрятано. и можно получить этот объект

var_dump($this->view);
 

Духовность™

Продвинутый новичок
Ну дк вывод - MVC в PHP это не ооп, а стиль программирования?!
что значит не ООП? По факту ООП начинается тогда, когда хотя бы два объекта могут между собой иметь зависимости, взаимодействовать. Я вообще не понял, причем тут ООП и почему "MVC в PHP это не ооп"..

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

craz

Нестандартное звание
что значит не ООП? По факту ООП начинается тогда, когда хотя бы два объекта могут между собой иметь зависимости, взаимодействовать. Я вообще не понял, причем тут ООП и почему "MVC в PHP это не ооп"..

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

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

Духовность™

Продвинутый новичок
Я согласен, что 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

Administrator
Команда форума
Активист
Я понимаю некоторое твоё недоумение, но причем здесь ООП я тоже не понимаю.
MVC в общем виде - это не ООП-паттерн.

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