Пример MVC в php. Пятая статья. Исправление неточностей

Содержание цикла статей:

Исправление неточностей в структуре MVC

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

Переработав исходники, я совсем выкинул из структуры класс registry — реест, который изначально создавался как хранилище данных. Но в последствии стал не нужным, поскольку передача данных между контроллером и вьюхами, осуществляется через класс Template. А передача данных в модель реализована через абстрактный родительский класс Model_Base.
Также помимо правок структуры, был исправлен Router — роутер, который отвечает за вызов нужного контроллера и экшена, анализируя адрес страницы. Был исправлен баг с определением путей до контроллеров, при использовании данного примера MVC на *nix системах. Помимо путей, определяемых в роутере, был немного подправлен индексный файл, а именно путь до конфигураций.
И последнее исправление, точнее дополнение, было сделано в индексном файле — index.php. При подключении базы данных, была реализована установка кодировки:

$dbObject->exec('SET CHARACTER SET utf8');

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

Рассказать друзьям:


Пример MVC в php. Пятая статья. Исправление неточностей: 24 комментария

  1. Очень вам благодарен за проделанную работу.
    Очень хотелось бы прочесть статью о шаблонизаторах и выборе одного из них или оставить php в качестве шаблонизатора. Ибо в MVC шаблонизатора не использовалось помимо самого php.

    1. Я пробовал несколько шаблонизаторов — smarty, dwoo и twig. Использовались они в основном в сочетании с фреймворками. Честно говоря, каких-то весомых плюсов перед обычным выводом с помощью php я не увидел. Но в их использовании есть минусы, самый главный это, то что они замедляют вывод вьюхи, отображение сайта происходит медленней. Хоть и не значительно, но все же сайты с использованием шаблонзаторов работают медленней. Есть и еще один минус — у каждого шаблонизатора, свой синтаксис, с которым тоже в первое время работы приходится разбираться. А справок по некоторым не так много, а что есть, та в основном на английском языке.
      Я бы не советовал подключать шаблонизаторы на простеньких сайтах, на которых весь смысл их использования сводится к простому выводу информации. Да и на крупных сайтах, с большим функционалом, желательно писать всю логику в контроллерах или моделях, а в шаблонах делать минимальные действия — коротенький цикл, условие и вывод. В идеале — только вывод.

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

  2. В модели Model_Base
    есть метод:
    _getResult
    в нем:
    $stmt = $db->query($sql);
    $rows = $stmt->fetchAll();

    а где описаны: методы query и fetchAll ?

  3. Спасибо за замечательный цикл статей! Наконец нашла доступный для моего понимания пример реализации. С большим нетерпением жду анонсированного продолжения про комментарии.

  4. Прекрасные статьи, наконец даже такой как я начал что-то понимать) Только не все работает, и соответственно есть вопрос, откуда в ruter.php взялось $_GET[‘route’] и что там должно храниться? адресная строка то примерно такая http://localhost/warr/index.php?id=2, $_GET[‘id’] есть, а откуда ‘route’ хз.
    PS знаю вопрос тупой, но все же интересные статьи, хочу разобраться.

  5. Предлагаю поправить файл mvc_5.sql

    так как в том порядке создания таблиц который в нем приведен — будет возникать ошибка при создании таблиц (нарушение целостности)
    правильнее было бы так:

    — начало файла
    CREATE TABLE IF NOT EXISTS `comments` (
    `id` int(10) NOT NULL AUTO_INCREMENT,
    `user_name` varchar(50) DEFAULT NULL,
    `text` text,
    `date_create` datetime DEFAULT NULL,
    `is_active` tinyint(1) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    CREATE TABLE IF NOT EXISTS `category` (
    `id` int(10) NOT NULL AUTO_INCREMENT,
    `name` varchar(50) DEFAULT NULL,
    `is_active` tinyint(1) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

    INSERT INTO `category` (`id`, `name`, `is_active`) VALUES
    (1, ‘Категория 1’, 1),
    (2, ‘Категория 2’, 1),
    (3, ‘Категория 3’, 1);

    CREATE TABLE IF NOT EXISTS `article` (
    `id` int(10) NOT NULL AUTO_INCREMENT,
    `id_category` int(10) DEFAULT NULL,
    `title` varchar(255) DEFAULT NULL,
    `small_text` text,
    `text` text,
    `date_create` date DEFAULT NULL,
    `is_active` tinyint(1) DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `article_fk1` (`id_category`),
    CONSTRAINT `article_fk1` FOREIGN KEY (`id_category`) REFERENCES `category` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

    INSERT INTO `article` (`id`, `id_category`, `title`, `small_text`, `text`, `date_create`, `is_active`) VALUES
    (1, 1, ‘Заголовок статьи 1’, ‘Короткое описание статьи’, ‘Полный текст статьи’, ‘2014-03-30’, 1),
    (4, 1, ‘Заголовок статьи 2’, ‘Короткое описание статьи’, ‘Полный текст статьи’, ‘2014-03-30’, 1),
    (5, 1, ‘Заголовок статьи 3’, ‘Короткое описание статьи’, ‘Полный текст статьи’, ‘2014-03-30’, 1),
    (6, 2, ‘Заголовок статьи 4’, ‘Короткое описание статьи’, ‘Полный текст статьи’, ‘2014-03-30’, 1),
    (7, 2, ‘Заголовок статьи 5’, ‘Короткое описание статьи’, ‘Полный текст статьи’, ‘2014-03-30’, 1),
    (8, 2, ‘Заголовок статьи 6’, ‘Короткое описание статьи’, ‘Полный текст статьи’, ‘2014-03-30’, 1),
    (9, 2, ‘Заголовок статьи 7’, ‘Короткое описание статьи’, ‘Полный текст статьи’, ‘2014-03-30’, 1);
    — конец файла

  6. в классе Controller_Base можно удалить protected $registry; — все равно не используется :-))

  7. Спасибо за статьи. Долго искал что-нибудь простое и наглядное про MVC. А конкретно про реализацию этого шаблона на примере простенького сайта. Надеюсь будет продолжение — комментарии и админка.

  8. Благодарен за статью, очень интересно, и доходчиво. Хотелось бы почитать подробнее про использование PDO и MYSQLI, в модели приложений. Думаю, многим это также интересно, ведь здесь возникает больше всего проблем.
    А также момент тестирования — можно ли при разработке интегрировать в контроллеры отдельный класс для тестирования?
    Спасибо.

  9. Здравствуйте! Большое спасибо за статьи — очень наглядный MVC движок на PHP.

    Подскажите пожалуйста:
    Хочу добавить работу с сессиями и авторизацию, но постоянно косяк. Есть файл auth.php, который я подключил в index.php после core.php:


    // подключаем авторизатор
    require (SITE_PATH . DS . 'classes' . DS . 'auth.php');

    Вот его код:

    "login = '".$name."' AND pass = '".md5($pass)."'",
    );
    $model = new Model_Users($select);
    $model->fetchOne();
    $user_data = array(
    'user_name' => $model->user_name,
    'avatar' => $model->avatar
    );

    if ( isset($model->id) ) {// до сюда доходит нормально, все данные корректные
    session_start(); // логин пароль совпали, авторизация проходится
    $_SESSION['user_id'] = $model->id;
    $_SESSION['user_role'] = $model->role;
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
    $_SESSION['user_data'] = $user_data;
    }
    header("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
    exit;
    }
    if (isset($_GET['action']) AND $_GET['action']=="logout") {
    session_start();
    session_destroy();
    header("Location: http://".$_SERVER['HTTP_HOST']."/");
    exit;
    }
    if (isset($_REQUEST[session_name()])) session_start();

    А вот кусок лайаута:

    Hallow, !

    Потом во вьюхах я хочу с помощю блока if/else чекать $_SESSION[‘user_id’] и $_SESSION[‘user_role’] для скрытия\отображения блоков.

    Но вот беда:
    Undefined variable: _SESSION in ..\first_layouts.php
    И с первого входа, и после сабмита формы одно и тоже.
    Причем эта авторизилка работала с, напирмер, одностраничником.
    Может я что напутал в паттерне MVC?

    Пробовал дампить логин и пароль — совпали, авторизация проходится, модель из базы достает…

    Очень надеюсь что ткнете носом)

    1. Админ, извини за флуд
      Два раза уже неполучилось код запостить
      Удали пжл ответы из под моего поста и не сердись :3

  10. Просто спасибо вам большое! Цикл статей очень полезный! Творческих вам успехов)

    1. В router.php внизу ищи строку $controller->$action(); изменяй её на $controller->$action($args); , далее при URL site.ru/controller/action/9 сам экшн можно написать вот так
      function action($id) {
      var_dump($id);
      }

      Так мы и выведем эту цифру 9.

  11. Спасибо еще раз за статью, с азами все понятно и доступно !

    вопрос про реализацию:
    например, пользователь зашел на сайт, написанный в концепции МVC, затем перешел в какой то раздел, и только потом решил авторизоваться…
    каким образом обычно запоминается текущее положение на сайте ?

    Вообще интересно как технически реализуется функционирование различных блоков на сайте ? ведь действие будет только одно (переданное через роутер контроллеру) — то есть делается какое то хранилище промежуточного состояния ?

    решали ли вы такие задачи ? можете ли привести какие то примеры ?

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

  12. При сохранении текстовых данных все хорошо, но беда случается, когда в тексте появляются двойные кавычки. Вылетает ошибка по SQL запросу. Пока решил проблему поменяв местами сами кавычки в коде в строках базовой модели.
    Было: $arrayForSet[] = $field . ‘ = » ‘ . $this->$field . » ‘ «;
    Стало: $arrayForSet[] = $field . » = ‘ » . $this->$field .’ » ‘;

    Но учтите, это просто костыль. Если в тексте появятся одинарные кавычки, будут ошибки. Нужно ескепить их, но для PDO не силен.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*