За последние 24 часа нас посетили 20670 программистов и 1106 роботов. Сейчас ищет 351 программист ...

В чём приемущество MVC

Тема в разделе "Прочие вопросы по PHP", создана пользователем Mr.M.I.T., 29 янв 2009.

  1. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    флоппик
    там написанно, расширяемый, гибкий - как раз то что нужно
    а то у меня творческий кризис...
     
  2. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Mr.M.I.T.
    Я скажу следующее. Пришел на работу. Впервые работал в коллективе и над таким крупным сайтом. Там был MVC, с которым я впервые и познакомился. В первый же день я смог выполнить пару заданий. Спустя трое суток я уже без особых сложностей выполнял задания.
    Очень было удобно: нужно внести изменения на какой-то странице -- зашел в базу, посмотрел контроллер, внес изменения, потом шаблон подкорректировал. Новый раздел было создать тоже проще пареной репы: сделал запись в базе, создал шаблон и контроллер, по необходимости дописал метод в модели.
    А что нужно сделать, чтобы создать новый раздел в сайте, где код слитно? Сначала найти, куда вставить, затем писать кучу методов, которые похожи на предыдущие, разобраться, как работают предыдущие.

    Конечно, если сайт пишешь для себя, то для MVC нет необходимости, ибо стандартизация всегда занимает больше времени чем солянка. Хотя я сейчас стараюсь поднимать MVC, чтобы научиться писать грамотное приложение. Надеюсь, что в жизни пригодится.
     
  3. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
    в 4-й или 5-й раз :) сбился со счёта уже…

    кстати, большинство фрэймворком умеют для конечного сайта собирать все инклюды в 1 большой файл и потом подключать его.
    главное, чтобы через пару месяцев не пришло в голову что-то изменить или добавить. А то в эту солянку лезть…
     
  4. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    забавный ночью был диалог.
    - будем писать с применением MVC?
    я: в прямом виде - нет, много гемора.
    но обработка ввода должна быть жестко отделена от вывода и мало зависеть от структуры данных.
    - так это и есть MVC )))
     
  5. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    // Во, еле отправил сообщение
    ща с ходу попробую написать что сейчас у меня в голове 0о
    http://codepaste.ru/1558/
    вот с ходу написал,
    что это у нас получилось?
     
  6. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    т.е. я о чём
    вот этот
    это и модель и контроллер, ну единственное что вид в шаблоне
     
  7. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    но шаблон с логикой, циклами и пр.
     
  8. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Дело не в инклудах: эта проблема решается путем сбора на продакшене всего в packages и zendguard'ом их.

    Тут основная мысль именно в разделении всего кода на три смысловые части: модели, шаблоны и связующие звенья - контроллеры.

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

    Шаблон тоже решает узкую задачу: взять набор данных и отобразить в нужном виде. Вот КАК отобразить - это он знает. Шаблон совершенно не в курсе откуда эти данные. У него есть массив характеристик товара, он и выводит название свойства - жирным, значение - просто текстом. Или если это JSON-шаблон, то он преобразует данные в JSON-нотацию и отдает. Если это SAP-шаблон, то отдает в виде SAP.

    Контроллер знает какие данные из каких моделей нужны и какой шаблонизатор вызвать.


    Классика жанра: страница описания товара.
    Контроллер:
    1. дергает модель меню и получает структурированный список меню в виде, например, многомерного массива;
    2. Дергает модель «товар», метод «получить описание по идентификатору». В ответ получает тот же массив с описанием. Или исключение «товара с таким идентификатором нет». Или другую ошибку.
    3. Решает, что нужно выводить. Если есть ошибки, то какую-то страницу с ошибкой или «404» или еще что.
    4. Дергает нужный шаблонизатор и отдает ему данные.

    Т.е. вся логика построения сайта находится в контроллерах.

    Как-то так :)
     
  9. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    А что это?
     
  10. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Это я букву О пропустил. :) SOAP
     
  11. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Ну я так и подумал, спросил на всякий пожарный :)
     
  12. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    у меня вопрос. Почему на троих один контроллер и одна вьюшка? Что будет, если на каждую модель заводить по отдельному контролеру и вьюшке?
     
  13. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    У мну вот тоже всё разделено (причём жестко - весь HTML тока в темплейтах), однако до класического представления об MVC у мну как до луны. Тем неменее всё логично, красиво и есть модуль + темплейты. Контроллер тоже есть, но один глобальный и отвечает за загрузку нужных модулей в зависимости от вызванного модуля в URL. С ajax вообще проще парёной репы, даже шаблоны не нужно - выставил глобальный шаблон для ajax, сделал $parser->set('content', json_encode($data)); и всё - отличия от HTML vs JSON буквально в одной-двух строках, у мну методы выводят HTML и JSON чисто в зависимости от параметра где это надо :)
     
  14. sylex

    sylex Активный пользователь

    С нами с:
    9 ноя 2008
    Сообщения:
    625
    Симпатии:
    0
    Адрес:
    Омск
    по-моему такое может спросить ток человек, который плохо знаком с MVC..
     
  15. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    sylex
    и по- моему
     
  16. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    эх, парни, а мы вот тут на высоконагруженных проектах все руками. все по старинке. как я вам завидую...

    <title><?php =$title; ?></title>
     
  17. akrinel

    akrinel Активный пользователь

    С нами с:
    26 янв 2009
    Сообщения:
    955
    Симпатии:
    1
    Адрес:
    Spb
    440Hz, просвети юного падавана, если не трудно:

    Один мой знакомый утверждал, что(вольное цитирование):
    Это неверное мнение? Таки в высоконагруженных проектах о всяком ООП можно смело забыть?
     
  18. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    akrinel нет. просто 99% "высоконагруженых проектов" начинаются писаться студентами и не руками. а потом переделывать поздно...

    (а вот я сейчас от регистер глобалз уйти не могу

    и как убедить отказаться от onpropertychange и нестандартных свойств - (field.mypror = 5) - не представляю..
    )
     
  19. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Я использую и всё прекрасно работает. Другое дело что я не использую магию и заведомо тяжелые реализации. Всё легковесно и продумано. От идей, где заведомо требуется реализация в виде хорошего куска кода, который явно будет много юзатся и вносить приличный overhead нафиг отказываюсь сходу. Стараюсь использовать как можно меньше памяти, в последней наработке даже ввёл такое понятие, как глобальные шаблонные переменные - те живут постоянно, остальные чистятся сразу при первом же доступе (иначе в итоге скапливается большое кол-во массивов в уже ненужными данными). Так же был затык с генерацией PDF, когда в реализации отсуствовала принудительная отчистка свойств объектов. В итоге каждый следующий документ добавлял по 2 мега memory usage, т.е. больше 5-6 документов сгенерировать, а мне нужно было генерировать по 2-3 тысячи. Т.к. легкого решения небыло, пришлось сделать скрипт, который в цикле вызывал консоль и генерировал по документу, однако урок на будущее я вынес - деструкторы с отчисткой данных при реализации классов-библиотек, особенно всякие парсеры-конвентеры, обязательны. Удаление результатов баз данных - тоже обязательно, особенно если они большие. Иначе переменные то удаляются, а вот занимаемая данными память может и не освободится. В 5.3 конечно сделали garbige collector, который можно принудительно вызвать, но это затык в производительности, особенно если мусора много, оно скорее для консольных демонов, где небольшая пауза в 100 мс позволительна (цифра для примера).
     
  20. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    440Hz
    Я по сути почти так же делаю, тока чуть чуть ООП :)

    PHP:
    1. <?php
    2. $parser->set('site_title', _("Мой мега заголовок"));
    3.  
    HTML:
    1.  
    2. <title><?php echo $this->get('site_title')?></title>
    3.  
    Никакой мега ООП логики под этим нету, просто глобальный объект. В одном месте запихнул, в другом вытащил. Lookup scope поменьше чем глобальный, поетому работает шустрее чем просто в глобальном пространстве хранить переменные.
     
  21. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    конечно нет. просто в том проекте который я делаю легче и быстрее написать се руками и не парится, чем замораыиватся со всякими изысками.

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

    эх...
     
  22. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    переведи.
     
  23. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    armadillo
    По русски - кто-то предложил прикольную ООП поебень (к примеру класс-обёртку для базы данных, где простейшие SELECT, UPDATE, INSERT запросы генерируются из ассоциативного массива, да ещё и с data binding в объекты), которая использует PHP ООП по полной, т.е. magic методы и прочее - она идёт на три буквы т.к.:
    1). Magic OOP в PHP весьма медлителен
    2). Это ещё кусок кода в 300 (а то и 1000) строк кода, без которого можно обойтись и вполне написать десяток лишних строк на месте и под конкретную задачу, чем хренячить целый объект универсальный. В крайнем случае оформляю как более-менее универсальную функцию, которая сокращает это до 2-3 строк на месте вызова.

    Вообщем у мну баланс между объектами и функциями.
     
  24. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    Psih аналогично (было на предыдущей работе) ))
    вопрос тут не в объеме кода, а в том, насколько это читаемо и сколько выносит повторяемого кода.
     
  25. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    armadillo
    Повторяется в 2-х местах - в функцию. Повторяется довольно сложный функционал - в класс-помошник (т.е. там, где есть от этого смысл).

    К примеру у меня есть 2 статические функции: encode и decode (кодируют ID'ки, что бы нельзя было последовательным перебором легко бегать по ссылкам), они используются прям повсеместно, как в нутри модулей, так и местами вне их. Несмотря на то, что там ещё реализация CRC16 и ещё пара функций, необходимых для их работы - в класс я их не оформлял - просто вынес в библиотечный файл функций. С другой стороны "шаблонизатор". Там вроде всего пара методов да массив с данными: get/set/append/load - последнее загружает template - тоже можно оставить в виде функций, но гораздо больше смысла сделать в виде класса:
    1). Все данные храняться в нутри объекта в приватном поле.
    2). Можно реализовать кеширование темплейтов, проверку на существование данных, и.т.д. Последнее кстати есть и очень легко делать в шаблонах вывод что данных нет (пример приведу ниже).
    3). Всё аккуратно, красиво, никаких граблей.

    А вот и пример типичной реализации блока с выводом каких-то данных:

    PHP:
    1. <?php
    2.  
    3. class Dummy extends ModuleCore {
    4.    
    5.     /**
    6.      * Holds a reference to a DB object
    7.      *
    8.      * @var DB
    9.      */
    10.     private $db;
    11.    
    12.     public function __construct(DB &$db, $param)
    13.     {
    14.         $this->db = &$db;
    15.        
    16.         switch ($param) {
    17.             case CENTER_SUB:
    18.                 $this->showDefault();
    19.                 break;
    20.                
    21.             case CENTER:
    22.                 $this->show(ARG1);
    23.                 break;
    24.            
    25.             default:
    26.                 forward();
    27.         }
    28.     }
    29.     private function show($page) {
    30.         global $parser, $settings, $session;
    31.        
    32.         $sql = 'SELECT something
    33.                 FROM somethere1 AS s1
    34.                 LEFT JOIN somethere2 AS s2 ON s2.id = s1.s2_id
    35.                 WHERE s1.field = '.$session['auth']['id'];
    36.         $r = $this->db->query($sql);
    37.         if ($r && $r->num_rows) {
    38.             $rows = array();
    39.             while ($row = $r->fetch_assoc()) {
    40.                 // Do something with $row
    41.                 $rows[] = $row;
    42.             }
    43.             $parser->set('data', $rows);
    44.         }
    45.         $parser->append('content_center', $this->toBox(_("Заголовок блока"), $this->template('show.htm')));
    46.     }
    47. }
    48.  
    А вот и сам шаблон
    PHP:
    1.  
    2. <?php if (!$parser->is_set('data')):?>
    3.     <div class="message"><?php echo _("Данные отсутствуют")?></div>
    4. <?php else:?>
    5.     <table class="designed">
    6.         <tr>
    7.             <th><?php echo _("Заголовок 1")?></th>
    8.             <th><?php echo _("Заголовок 2")?></th>
    9.             <th><?php echo _("Заголовок 3")?></th>
    10.         </tr>
    11.         <?php $i = 0; foreach ($parser->get('data') as $val):?>
    12.             <tr class="<?php echo ++$i % 2 ? 'odd' : 'even'?>">
    13.                 <td><?php echo $val['field_1']?></td>
    14.                 <td><?php echo $val['field_2']?></td>
    15.                 <td><?php echo $val['field_3']?></td>
    16.             </tr>
    17.         <?php endforeach;?>
    18.     </table>
    19. <?php endif;?>
    20.