Статьи

HMVC: введение и применение

Это руководство представляет собой введение в шаблон HMVC и его применение к разработке веб-приложений. В этом руководстве я буду использовать примеры из CodeIgniter из серии Scratch и продемонстрирую, как HMVC может быть ценной модификацией в вашем процессе разработки. В этом введении предполагается, что вы понимаете паттерн Model View Controller (MVC). Мы предлагаем вам прочитать наше введение в MVC, чтобы ознакомиться с этой темой, прежде чем приступать к изучению этого руководства.

HMVC — это эволюция шаблона MVC, используемого сегодня для большинства веб-приложений. Это стало ответом на проблемы с продажностью, очевидные в приложениях, которые использовали MVC. Решение, представленное на веб-сайте JavaWorld в июле 2000 года, предложило превратить стандартную триаду Model, View и Controller в « иерархию родительско-дочерних уровней MCV ». Изображение ниже иллюстрирует, как это работает:

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

Ключевые преимущества для реализации шаблона HMVC в вашем цикле разработки:

  • Модуляризация: сокращение зависимостей между различными частями приложения.
  • Организация: Наличие папки для каждой соответствующей триады облегчает работу.
  • Возможность повторного использования: по своей природе дизайн позволяет легко использовать практически каждый фрагмент кода.
  • Расширяемость: делает приложение более расширяемым, не жертвуя простотой обслуживания.

Эти преимущества позволят вам получить больше от вашего приложения с меньшими головными болями.

Чтобы добавить дополнительную глубину CodeIgniter из серии Scratch , мы рассмотрим сегодняшние примеры в CodeIgniter. Я приведу нас, хотя шаги, необходимые для работы CodeIgniter с HMVC. Как только мы закончим с этим, я приведу пару примеров. Давайте начнем!

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

Перейдите на codeigniter.com и нажмите ссылку «Загрузить CodeIgniter». Если вы знаете, как установить его и хотите пропустить этот шаг, нажмите здесь

Извлеките содержимое zip-файла в корневой каталог вашего веб-сервера.

Переименуйте папку « CodeIgniter_1.7.2 » в « hmvcExample ».

Переместите папку « hmvcExample / system / application » в « hmvcExample / application ». Это обычная практика с CodeIgniter. Цель этого состоит в том, чтобы отделить приложение от ядра платформы. Теперь у нас должен быть каталог, похожий на изображение ниже:

Откройте « hmvcExample / application / config / config.php » в выбранном вами редакторе.

Измените базовый URL сайта в соответствии с местоположением вашей установки. В моем случае я бы изменил

1
$config[‘base_url’] = «http://example.com/»;

в

1
$config[‘base_url’] = «http://localhost/hmvcExample/»;

Сохраните ваши изменения и закройте « hmvcExample / application / config / config.php »

Проверьте, что у нас есть рабочая версия CodeIgniter. Откройте браузер и проверьте ваш «http: // yourhost / hmvcExample /».
Вы должны увидеть экран «Добро пожаловать в CodeIgniter» ниже:

Это оно! Вы успешно загрузили и установили CodeIgniter. Теперь перейдем к тому, чтобы заставить его работать с расширением HMVC.

Загрузите версию 5.2 модульного расширения из CodeIgniter Wiki .

В содержимом zip-файла находятся три php-файла:

Переместите эти три файла в папку « hmvcExample / application / library / ».

Перепроверьте свой браузер. Вы все равно должны увидеть экран Welcome to CodeIgniter.

Пришло время добавить модули. Создайте следующую структуру каталогов « application / modules / welcome / controllers / ».

Переместите « application / controllers / welcome.php » в « application / modules / welcome / controllers / welcome.php ».

Перепроверьте свой браузер. Вы все равно должны увидеть экран Welcome to CodeIgniter.

Создайте папку « application / modules / welcome / views / »

Переместите « application / views / welcome_message.php » в « application / modules / welcome / views / welcome_message.php ».

Сделайте последнюю проверку в вашем браузере. Вы все равно должны увидеть экран Welcome to CodeIgniter.

Это оно! Модульные расширения установлены правильно.

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

Загрузите и распакуйте CodeIgniter из исходных файлов Scratch Day 6 на свой веб-сервер. Вы должны получить папку с именем » ci_day6 / » рядом с нашим » hmvcExample / «

Создайте модуль « login » в нашем каталоге « hmvcExample / application ». Это должно выглядеть так

1
2
3
hmvcExample/application/modules/login/controllers/
   hmvcExample/application/modules/login/models/
   hmvcExample/application/modules/login/views/

Создайте модуль «site» в нашем каталоге «hmvcExample / application». Это должно выглядеть так

1
2
3
hmvcExample/application/modules/site/controllers/
   hmvcExample/application/modules/site/models/
   hmvcExample/application/modules/site/views/

СОВЕТ: При работе с модулями я сохраняю папку с именем RENAME с тремя пустыми папками контроллеров, моделей и видов. Это сэкономит мне немного времени, когда я захочу создать новую модель.

Теперь мы копируем файлы модуля входа из « ci_day6 / » в наш « hmvcExample / ».

1
2
3
4
5
ci_day6/application/controllers/login.php
   ci_day6/application/models/membership_model.php
   ci_day6/application/views/login_form.php
   ci_day6/application/views/signup_form.php
   ci_day6/application/views/signup_successful.php

Скопируйте / переместите каждый из перечисленных выше файлов, как указано ниже

1
2
3
4
5
hmvcExample/application/modules/login/controllers/login.php
   hmvcExample/application/modules/login/models/membership_model.php
   hmvcExample/application/modules/login/views/login_form.php
   hmvcExample/application/modules/login/views/signup_form.php
   hmvcExample/application/modules/login/views/signup_successful.php

Затем мы копируем файлы модуля сайта из » ci_day6 / » в наш » hmvcExample / «.

1
2
ci_day6/application/controllers/site.php
   ci_day6/application/views/logged_in_area.php

Скопируйте / переместите каждый из перечисленных выше файлов, как указано ниже

1
2
hmvcExample/application/modules/site/controllers/site.php
   hmvcExample/application/modules/site/views/logged_in_area.php

Последние файлы для копирования — это глобальные представления, CSS и файлы изображений. Звездочкой ( * ) обозначена папка и все ее содержимое, включая подпапки

1
2
3
ci_day6/css/*
ci_day6/img/*
ci_day6/application/views/includes/*

Скопируйте все указанные выше папки и все их содержимое, как указано ниже.

1
2
3
hmvcExample/css/*
hmvcExample/img/*
hmvcExample/application/views/includes/*

Откройте « hmvcExample / application / config / autoload.php » и отредактируйте его, чтобы он выглядел так:

01
02
03
04
05
06
07
08
09
10
11
12
13
$autoload[‘libraries’] = array(‘database’, ‘session’);
 
 
/*
|
|
|
|
|
|
*/
 
$autoload[‘helper’] = array(‘url’, ‘form’);

Если вы еще не сделали этого с первого шага, откройте « hmvcExample / application / config / config.php » и отредактируйте его так, чтобы в качестве базового URL- адреса было выбрано нужное вам местоположение.

1
$config[‘base_url’] = «http://localhost/hmvcExample/»;

Откройте « hmvcExample / application / config / database.php » и добавьте соответствующие ссылки в вашу базу данных.

1
2
3
4
$db[‘default’][‘hostname’] = «localhost»;
$db[‘default’][‘username’] = «YOUR USERNAME HERE»;
$db[‘default’][‘password’] = «YOUR PASSWORD HERE»;
$db[‘default’][‘database’] = «ci_series»;

Откройте браузер, чтобы проверить, что на странице входа отображается « http: //localhost/hmvcExample/index.php/login »

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

Выберите или создайте свою базу данных » ci_series «.

На вкладке sQL вставьте приведенный ниже код в текстовую область и нажмите кнопку «Перейти».

1
2
3
4
5
6
7
8
CREATE TABLE `ci_series`.`membership` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`first_name` VARCHAR( 32 ) NOT NULL ,
`last_name` VARCHAR( 32 ) NOT NULL ,
`email_address` VARCHAR( 64 ) NOT NULL ,
`username` VARCHAR( 32 ) NOT NULL ,
`password` VARCHAR( 32 ) NOT NULL
) ENGINE = MYISAM ;

Создав таблицу членства, мы нажимаем ссылку « Создать учетную запись» на странице входа и добавляем пользователя в базу данных.

Войдите в систему как пользователь и подтвердите, что вы сейчас находитесь в » site / members_area » сайта. Это должно выглядеть примерно так, как показано ниже:

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

Итак, у нас сгруппированы триады, но мы все еще не совсем в режиме HMVC. В контроллере сайта мы находим функцию is_logged_in ().

1
2
3
4
5
6
7
8
9
function is_logged_in()
   {
       $is_logged_in = $this->session->userdata(‘is_logged_in’);
       if(!isset($is_logged_in) || $is_logged_in != true)
       {
           echo ‘You don\’t have permission to access this page.
           die();
       }
   }

Это функция входа в систему. В режиме MVC это требуется, поскольку сайт не может получить доступ к входу в систему. С HMVC мы можем это исправить.

Вырежьте функцию is_logged_in () из » application / modules / site / controllers / site.php «

Сохраните site.php без функции is_logged_in ().

Откройте « Applications / modules / login / controllers / login.php ».

Вставьте функцию is_logged_in () в класс.

Сохраните login.php

Откройте « Applications / modules / site / controllers / site.php ».

1
2
3
4
5
function __construct()
   {
       parent::Controller();
       $this->is_logged_in();
   }

В функции __Construct () мы выполняем HMVC-вызов функции is_logged_in () входа в систему, как показано ниже:

1
2
3
4
5
6
function __construct()
   {
       parent::Controller();
       // Format: modules::run(‘module/controller/action’, $param1, $param2, .., $paramN);
       modules::run(‘login/is_logged_in’);
   }

Вот оно! Мы успешно изменили код шестого дня в формат HMVC. Модуль сайта теперь запрашивает проверку входа вместо того, чтобы использовать свою собственную. Хотя внешне мы не видим никакой разницы, дизайн сайта в корне изменился. Все функции входа в систему находятся там, где они должны быть: внутри триады входа в систему. Это может показаться большой работой с небольшим вознаграждением, но это не так. Любые изменения логина могут быть сделаны один раз. Внутренняя структура триады может быть отредактирована без необходимости изменения всего приложения в ответ. Репликация кода для других контроллеров больше не требуется. Наконец, что не менее важно, весь связанный код находится в одном удобном месте. Этот крошечный шаг, возможно, не ВАУ, но когда мы углубимся в более крупные и сложные приложения, БОЛЬШЕ станет очевидным, насколько эффективной будет модель HMVC.

Теперь мы собираемся раскрыть больше возможностей HMVC. Мы только что продемонстрировали, как вызвать модуль из контроллера. Есть и другие места, где вы можете сделать это. HMVC был построен с учетом пользовательского интерфейса (UI). В результате мы получаем вызовы модулей из наших представлений. Вот где мощь HMVC действительно может сиять.

При вызове HMVC из представления вы будете использовать те же модули modules :: run (). При этом существует только одно требование. Полученный результат вызова должен быть фрагментом html, а не полным представлением. Это потому, что мы уже находимся внутри представления во время вызова функции run. Мы увидим это в действии вниз по странице, когда будем редактировать представления модуля сайта.

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

Откройте « Applications / modules / login / controllers / login.php ».

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function cp()
   {
       if( $this->session->userdata(‘username’) )
       {
           // load the model for this controller
           $this->load->model(‘membership_model’);
           // Get User Details from Database
           $user = $this->membership_model->get_member_details();
           if( !$user )
           {
               // No user found
               return false;
           }
           else
           {
               // display our widget
               $this->load->view(‘user_widget’, $user);
           }
       }
       else
       {
           // There is no session so we return nothing
           return false;
       }
   }

Вставьте / напишите приведенный выше код в контроллер входа.

cp () получает информацию от функции members_model get_member_details (), которую мы создадим на следующем шаге. Если пользователь найден, мы отобразим фрагмент просмотра, подробно описанный на третьем шаге. Оттуда мы должны получить нужный блок, показанный выше.

Сохраните внесенные изменения в login.php

Вы заметите, что мы вызвали get_member_details () из members_model. Эта функция получает информацию о наших пользователях из базы данных и будет доступна из нескольких разных источников. Мы собираемся работать над этим сейчас.

Откройте « Applications / modules / login / models / members_model.php ».

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
function get_member_details($id=false)
   {
       if( !$id )
       {
           // Set Active Record where to the current session’s username
           if( $this->session->userdata(‘username’) )
           {
               $this->db->where(‘username’, $this->session->userdata(‘username’));
           }
           else
           {
               // Return a non logged in person from accessing member profile dashboard
               return false;
           }
       }
       else
       {
           // get the user by id
           $this->db->where(‘id’, $id);
       }
       // Find all records that match this query
       $query = $this->db->get(‘membership’);
       // In this case because we don’t have a check set for unique username
       // we will return the last user created with selected username.
       if($query->num_rows() > 0)
       {
           // Get the last row if there are more than one
           $row = $query->last_row();
           // Assign the row to our return array
           $data[‘id’] = $row->id;
           $data[‘first_name’] = $row->first_name;
           $data[‘last_name’] = $row->last_name;
           // Return the user found
           return $data;
       }
       else
       {
           // No results found
           return false;
       }

Прокомментируйте свой код! Это лучшая практика, которая поможет другим понять, что вы написали.

Строка 01: вызов функции имеет переменную по умолчанию $ id. Это позволяет нам найти пользователя по идентификатору, а не по имени пользователя. Это стало необязательным, установив значение false в объявлении.

Остальная часть функции проста и хорошо прокомментирована. Мы запрашиваем таблицу членства для пользователя через имя пользователя или идентификатор. Результат сохраняется в массиве $ data и возвращается. Все остальные результаты возвращают ложные.

Сохраните внесенные изменения в members_model.php

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

Откройте « apps / modules / login / views / user_widget.php ».

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<code style=»font-family: Monaco, Verdana, Sans-serif;
                 font-size: 12px;
                 background-color: #f9f9f9;
                 border: 1px solid #D0D0D0;
                 color: #002166;
                 display: block;
                 margin: 14px 0 14px 0;
                 padding: 12px 10px 12px 10px;»>
    <?php echo $first_name.’
    <?php echo anchor(‘site/members_area’, ‘Dashboard’);
    <?php echo anchor(‘site/profile/’.$id, ‘Profile’);
    <?php echo anchor(‘site/messages/’.$id, ‘Messages’);
    <?php echo anchor(‘login/logout’, ‘Logout’);
</code>

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

Этот стилизованный кодовый блок получает информацию, переданную из функции cp (). Мы генерируем ссылки, используя функцию anchor () помощника URL CodeIgniter. Более подробную информацию о руководстве пользователя можно найти на codeigniter.com .

После работы с этими тремя файлами мы протестируем страницу « login / cp ». Мы должны увидеть что-то похожее на изображение ниже. Примечание. Чтобы увидеть это, вам необходимо войти в систему int. Обязательно сделайте это перед проверкой страницы, иначе вы ничего не увидите.

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

Откройте « Applications / modules / site / controllers / site.php ».

01
02
03
04
05
06
07
08
09
10
11
12
13
<?php
class Site extends Controller
{
    function __construct()
    {
        parent::Controller();
    }
 
    function members_area()
    {
        modules::run(‘login/is_logged_in’);
        $this->load->view(‘logged_in_area’);
    }

__construct ()
Для целей этого примера мы удалим …

1
modules::run(‘login/is_logged_in’);

… из функции, чтобы мы могли сделать определенные части частными и сделать другие части общедоступными.

members_area ()
Мы хотим, чтобы только зарегистрированные пользователи имели доступ к области панели инструментов участников. Поэтому мы будем использовать модули: запустить функцию HMVC и вызвать проверку is_logged_in из контроллера входа в систему. Затем мы загружаем файл представления logged_in_area, который будет редактироваться дальше вниз по странице.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
function messages()
   {
       modules::run(‘login/is_logged_in’);
       $this->load->model(‘login/membership_model’);
       $user = $this->membership_model->get_member_details($this->uri->segment(3));
       if( !$user )
       {
           // No user found
           return false;
       }
       else
       {
           // display our widget
           $this->load->view(‘member_messages’, $user);
       }
   }

Сообщения()
Как и members_area (), мы хотим, чтобы вошли только пользователи, поэтому мы включили проверку is_logged_in. Мы уже написали код о том, как получить информацию о пользователе из базы данных, поэтому мы загрузим модель входа в систему, members_model. Это позволит нам получить информацию о пользователе с помощью функции get_member_details (). Третий сегмент URI, передаваемый в эту функцию, является идентификатором пользователя, для которого мы хотим получать сообщения. Например, если URL был:

1
http://localhost/hmvcExample/index.php/site/messages/43

Тогда наша функция get_member_details () получит «43» в качестве входной переменной. В зависимости от результата get_member_details () нам либо показывают view: member_messages, либо мы ничего не получаем (в результате неудачного запроса).

1
function profile() { $this->load->model(‘login/membership_model’);

профиль()
Как и в любой социальной сети; Мы хотим, чтобы страницы профиля были общедоступными. Поэтому мы не включили проверку is_logged_in. Как и сообщения, мы вызываем триаду login_model для входа в систему и запрашиваем базу данных для нашего желаемого пользователя. В этом случае, если пользователь не найден, мы уходим немного более изящно. Мы также уведомляем посетителя о том, что необходимо указать идентификатор. С успешным результатом мы видим профиль участника.

Откройте « Applications / modules / site / views / logged_in_area.php ».

01
02
03
04
05
06
07
08
09
10
11
12
<!DOCTYPE html>
<html lang=»en»>
<head>
    <meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″>
    <title>untitled</title>
</head>
<body>
    <?php echo modules::run(‘login/cp’);?>
    <h2>Welcome Back, <?php echo $this->session->userdata(‘username’);
     <p>This section represents the area that only logged in members can access.</p>
</body>
</html>

Перезапишите содержимое файла с кодом выше.

Строка 08: HMVC вводится в действие здесь. Наше представление вызывает функцию « login / cp » и выводит html-фрагмент именно там, где мы говорим. Заметьте, как нам не пришлось ничего готовить самим? Для нас все это внутренне обрабатывается логином для нас. Удобно не так ли?

Сохраните внесенные изменения в logged_in_area.php. Ваша готовая страница должна отображаться как:

Создайте новый вид: « apps / modules / site / views / member_messages.php ».

01
02
03
04
05
06
07
08
09
10
11
12
<!DOCTYPE html>
<html lang=»en»>
<head>
    <meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″>
    <title>untitled</title>
</head>
<body>
    <?php echo modules::run(‘login/cp’);?>
    <h2><?php echo $first_name;
     <p>This could be where the messaging system gets displayed</p>
</body>
</html>

Напишите или вставьте код выше во вновь созданный файл.

Это представление — всего лишь клон области участников, чтобы проверить, что логин удерживается на нескольких страницах. Есть одно отличие: мы выловили некоторую информацию из модуля members_model входа в систему. Это показано как переменная $ first_name.

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

Сохраните внесенные изменения в member_messages.php. Ваша готовая страница должна отображаться как:

Создайте новый вид: « apps / modules / site / views / member_profile.php ».

1
2
3
4
5
6
7
8
<?php echo modules::run(‘login/cp’);?>
   <?php if( isset($notice) ): ?>
   <h2>Member Profile Pages</h2>
   <p><?php echo $notice;
   <?php else: ?>
   <h2><?php echo $first_name;
    <p>Put all the good wholesome profile info here!</p>
   <?php endif;

Напишите или вставьте код выше во вновь созданный файл.

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

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

Сохраните внесенные изменения в member_profile.php. Ваша готовая страница должна отображаться как:

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

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

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

Это оно! Мы добавили больше глубины к нашему первоначальному примеру и продемонстрировали различные способы использования HMVC.

  • Вызовите модули: run () из контроллера.
  • Echo modules :: run () из представления для отображения фрагмента HTML.
  • Загрузите модель из другого модуля.

Я надеюсь, что это был полезный опыт. HMVC — это необычная модель, которая делает приложения более надежными. Это стоит вложений. Попробуйте. Я обещаю, что вы никогда не захотите возвращаться в Vanilla MVC!