Шаблон проектирования MVC и PHP, Часть 2

Добро пожаловать во вторую статью о MVC и PHP. В ней мы обсудим некоторые принципы, которыми следует руководствоваться при использовании архитектуры MVC.

Маршрутизация и URL-адреса

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

Так какие возможности у нас есть для решения проблемы URL-маршрутизации? Одна из них заключается в предопределении всех URL-адресов, которые нужны веб-приложению. А затем в их сохранении в хранилище вместе с соответствующими данными, которые шаблоны «Модели», «Представления» и «Контроллера» загружают для каждой страницы или раздела.

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

<?php
$page = $_GET['page'];
if (!empty($page)) {
    $data = array(
        'about' => array('model' => 'AboutModel', 'view' => 'AboutView', 'controller' => 'AboutController'),
        'portfolio' => array('model' => 'PortfolioModel', 'view' => 'PortfolioView', 'controller' => 'PortfolioController')
    );
    foreach($data as $key => $components){
        if ($page == $key) {
            $model = $components['model'];
            $view = $components['view'];
            $controller = $components['controller'];
            break;
        }
    }
    if (isset($model)) {
        $m = new $model();
        $c = new $controller($model);
        $v = new $view($model);
        echo $v->output();
    }
}

URL-адреса будут выглядеть следующим образом:

example.com/index.php?page=about

или

example.com/index.php?page=portfolio

MVC PHP пример загружает конкретный набор «Модели», «Представления» и «Контроллера» для запрашиваемой страницы. Если параметр URL-страницы - это “about”, то будет отображаться страница About. Если “portfolio”, то будет отображаться страница Portfolio.

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

Можно открыть доступ к определениям классов «Модели», «Представления» и «Контроллера», и разрешить URL-адресам определять их параметры. В статическом примере маршрутизации мы извлекаем идентификатор класса из массива, который содержит данные для маршрутизации, поступающие из постоянного хранилища. Замена массива с элементами превращает статическую маршрутизацию в динамическую.

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

Можно создать разделы или страницы, создавая взаимосвязи между «Моделью», «Представлением» и «Контроллером». Например:

<?php
$model = $_GET['model'];
$view = $_GET['view'];
$controller = $_GET['controller'];
$action = $_GET['action'];
if (!(empty($model) || empty($view) || empty($controller) || empty($action))) {
    $m = new $model();
    $c = new $controller($m, $action);
    $v = new $view($m);
    echo $v->output();
}

Наш новый URL-адрес будет выглядеть так:

example.com/index.php?controller=controllername;model=modelname&view=viewname&action=actionname

Текущая переменная URL-адреса сообщает системе, какую функцию нужно вызвать в «Контроллере». Когда эта функция передает данные в «Модель», она пересылает и часть данных, которые указывают, какое именно «Представление» и «Контроллер» нужно загрузить.

Это может быть переменная URL-адреса события, отдельная переменная или данные, собранные контроллером. Не забывайте, «Контроллер» никогда не должен загружать данные или непосредственно передавать их в «Представление»; он должен взаимодействовать только с «Моделью» и вводимыми пользователем данными.

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

Однако при динамической маршрутизации «Контроллер» может получить больше функций, чем при статической. Динамическую маршрутизацию можно рассматривать как модификацию традиционной MVC архитектуры. Тем не менее, если она реализована правильно и эффективно, «Контроллер» может стать более важным элементом, чем при статической маршрутизации.

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

DRY (Don’t Repeat Yourself) и шаблоны

Для меня одним из главных аргументов в пользу использования MVC является возможность сделать всю систему как можно более организованной. Любой разработчик согласится, что самое худшее для любого приложения – это повторение одного и того же кода. Принцип поддержания простоты кода и многократного использования компонентов получила название философия DRY - Don’t Repeat Yourself (не повторяйтесь).

Принципы DRY гласят: "Каждый фрагмент информации должен быть представлен в системе единожды, однозначно и понятно". Цель DRY - расширить и исследовать все возможные способы, доступные разработчикам, чтобы сделать систему динамичной и оптимизированной насколько это возможно. DRY подразумевает, что, если вам нужно написать один и тот же фрагмент кода во многих местах, то вместо повторения этого кода создайте отдельный метод и используйте его, где это необходимо.

Такой подход делает систему более оптимизированной и предусматривает возможность кэширования для сокращения общего времени обработки.

Корректная реализация DRY - это когда при изменении одного элемента системы несвязанные с ним элементы не меняются. Поэтому DRY так важен при разработке с использованием MVC паттерна.

Шаблоны

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

В идеале, «Представление» должно обрабатывать данные после их получения от «Модели». Поэтому имеет смысл организовать все так, чтобы компонент «Представление» только выбирал шаблон и передавал данные в этот шаблон.

Таким образом, данные будут готовы для отображения с помощью структуры блочного кода, или с помощью echo, print. Главное помнить, что ваши данные должны быть готовы для вывода через шаблон. Если у вас в шаблоне данные обрабатываются по-другому, скорее всего, у вас неверно задана архитектура MVC.

Вот простой пример того, как представление загружает шаблон и передает в него данные:

<?php
class Model
{
    public $tstring;
    public function __construct(){
        $this->tstring = "The string has been loaded through the template.";
        $this->template = "tpl/template.php";
    }
}
<?php
class View
{
    private $model;
    public function __construct($model) {
        $this->controller = $controller;
        $this->model = $model;
    }
    public function output(){
        $data = "<p>" . $this->model->tstring ."</p>";
        require_once($this->model->template);
    }
}
<!DOCTYPE html>
<html>
 <head>
  <meta charset="charset=utf-8">
  <title>The Template name</title>
 </head>
 <body>
  <h1><?php echo $data; ?></h1>
 </body>
</html>

Шаблон PHP MVC передается через «Модель», которая может назначать шаблон в зависимости от того, для чего предназначено каждое конкретное «Представление». Этот метод шаблонов позволяет создавать эффективные и расширяемые системы, предоставляя возможность разделения back-end и front-end разработки. В этом и заключается основная цель MVC.

Заключение

MVC претерпел серьезные изменения с тех пор, как он впервые был использован для программирования. Он был и до сих пор остается одной из самых обсуждаемых тем в среде разработчиков. Эти споры стали еще более интенсивными после того, как MVC стал использоваться для разработки на PHP для Веб.

Настоятельно рекомендую всем, кто не работал раньше с моделью MVC, уделить ей внимание, и вы не будете разочарованы.

Перевод статьи «The MVC Pattern and PHP. Part 2» был подготовлен дружной командой проекта Сайтостроение от А до Я.

15 февраля 2016 в 17:30
Материалы по теме
{"url":"http://www.fastvps.ru/", "src":"/images/advbanners/fastvps.png", "alt":"Хостинг Fastvps.ru. Наш выбор!"}
Заработок