Содержание цикла статей:
- 1. Вводная статья
- 2. Маршрутизация, контролеры, экшены, шаблоны
- 3. Модели. Элементарные действия с базой данных
- 4. Проектируем блог
- 5. Исправление неточностей структуры
Исправление неточностей в структуре MVC
Это пятая статья цикла, посвященного структуре MVC. Несколько месяцев назад, я выкладывал исходники структуры, которые получились в ходе написания предыдущих четырех статей. Я не ожидал, что этот цикл статей привлечет к себе столько внимания. Но посетители моего блога заинтересовались структурой MVC не на шутку, о чем свидетельствует множество комментариев и писем, отправленных мне на почту. Благодаря, этим людям, которые задавали вопросы и советовали свои решения, я поправил ранее написанную структуры.
Переработав исходники, я совсем выкинул из структуры класс registry — реест, который изначально создавался как хранилище данных. Но в последствии стал не нужным, поскольку передача данных между контроллером и вьюхами, осуществляется через класс Template. А передача данных в модель реализована через абстрактный родительский класс Model_Base.
Также помимо правок структуры, был исправлен Router — роутер, который отвечает за вызов нужного контроллера и экшена, анализируя адрес страницы. Был исправлен баг с определением путей до контроллеров, при использовании данного примера MVC на *nix системах. Помимо путей, определяемых в роутере, был немного подправлен индексный файл, а именно путь до конфигураций.
И последнее исправление, точнее дополнение, было сделано в индексном файле — index.php. При подключении базы данных, была реализована установка кодировки:
$dbObject->exec('SET CHARACTER SET utf8');
Эта статья оказалась коротенькая, но затронула много чего в коде, поэтому выкладываю новые отредактированные исходники — тут.
Также был залит пример работы новой структуры, посмотреть его можно тут.
Скоро цикл статей будет продолжен.
Очень вам благодарен за проделанную работу.
Очень хотелось бы прочесть статью о шаблонизаторах и выборе одного из них или оставить php в качестве шаблонизатора. Ибо в MVC шаблонизатора не использовалось помимо самого php.
Я пробовал несколько шаблонизаторов — smarty, dwoo и twig. Использовались они в основном в сочетании с фреймворками. Честно говоря, каких-то весомых плюсов перед обычным выводом с помощью php я не увидел. Но в их использовании есть минусы, самый главный это, то что они замедляют вывод вьюхи, отображение сайта происходит медленней. Хоть и не значительно, но все же сайты с использованием шаблонзаторов работают медленней. Есть и еще один минус — у каждого шаблонизатора, свой синтаксис, с которым тоже в первое время работы приходится разбираться. А справок по некоторым не так много, а что есть, та в основном на английском языке.
Я бы не советовал подключать шаблонизаторы на простеньких сайтах, на которых весь смысл их использования сводится к простому выводу информации. Да и на крупных сайтах, с большим функционалом, желательно писать всю логику в контроллерах или моделях, а в шаблонах делать минимальные действия — коротенький цикл, условие и вывод. В идеале — только вывод.
Возможно чуть позже, я напишу пример подключения шаблонизатора, но пока это в очень далекой перспективе, сейчас немного другие планы, относительно цикла статей по MVC.
Спасибо, с нетерпеньем жду новых статей.
Пример не работает со структурой типа
http://localhost/mvc/
В модели Model_Base
есть метод:
_getResult
в нем:
$stmt = $db->query($sql);
$rows = $stmt->fetchAll();
а где описаны: методы query и fetchAll ?
Все, сам понял, спасибо.
Спасибо за замечательный цикл статей! Наконец нашла доступный для моего понимания пример реализации. С большим нетерпением жду анонсированного продолжения про комментарии.
Прекрасные статьи, наконец даже такой как я начал что-то понимать) Только не все работает, и соответственно есть вопрос, откуда в ruter.php взялось $_GET[‘route’] и что там должно храниться? адресная строка то примерно такая http://localhost/warr/index.php?id=2, $_GET[‘id’] есть, а откуда ‘route’ хз.
PS знаю вопрос тупой, но все же интересные статьи, хочу разобраться.
.htaccess
RewriteRule ^(.*)$ index.php?route=$1 [L,QSA]
Большое спасибо. Жду новых статей)
Предлагаю поправить файл 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);
— конец файла
в классе Controller_Base можно удалить protected $registry; — все равно не используется :-))
Спасибо за статьи. Долго искал что-нибудь простое и наглядное про MVC. А конкретно про реализацию этого шаблона на примере простенького сайта. Надеюсь будет продолжение — комментарии и админка.
Благодарен за статью, очень интересно, и доходчиво. Хотелось бы почитать подробнее про использование PDO и MYSQLI, в модели приложений. Думаю, многим это также интересно, ведь здесь возникает больше всего проблем.
А также момент тестирования — можно ли при разработке интегрировать в контроллеры отдельный класс для тестирования?
Спасибо.
Здравствуйте! Большое спасибо за статьи — очень наглядный 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?
Пробовал дампить логин и пароль — совпали, авторизация проходится, модель из базы достает…
Очень надеюсь что ткнете носом)
Сайт побил куски кода в моем коменте))
Кусок лайаута еще раз:
if (isset($_SESSION['user_id']) AND $_SESSION['ip'] == $_SERVER['REMOTE_ADDR']) { ?>
Hallow, !
Админ, извини за флуд
Два раза уже неполучилось код запостить
Удали пжл ответы из под моего поста и не сердись :3
Просто спасибо вам большое! Цикл статей очень полезный! Творческих вам успехов)
У меня возник вопрос по роутеру
На данный момент ссылки имеют такой вид
http://sait.ru/category/?id=1
а мне надо вот так
http://sait.ru/category/categoryone
пока что сделал
http://sait.ru/category/?id=categoryone, а как скрыть get я не знаю!
========================
Подскажите плиз mr.melsitov@mail.ru
В router.php внизу ищи строку $controller->$action(); изменяй её на $controller->$action($args); , далее при URL site.ru/controller/action/9 сам экшн можно написать вот так
function action($id) {
var_dump($id);
}
Так мы и выведем эту цифру 9.
Спасибо еще раз за статью, с азами все понятно и доступно !
вопрос про реализацию:
например, пользователь зашел на сайт, написанный в концепции МVC, затем перешел в какой то раздел, и только потом решил авторизоваться…
каким образом обычно запоминается текущее положение на сайте ?
Вообще интересно как технически реализуется функционирование различных блоков на сайте ? ведь действие будет только одно (переданное через роутер контроллеру) — то есть делается какое то хранилище промежуточного состояния ?
решали ли вы такие задачи ? можете ли привести какие то примеры ?
P.s. понятно что скорее всего костыли для обхода подобных граблей у каждого будут индивидуальны, но хотелось бы увидеть какой то чужой опыт (с работающим решением) прежде чем изобретать свое..
А зачем смешивать в кучу доступ к бд (дао) и выдачу результата для показа?
При сохранении текстовых данных все хорошо, но беда случается, когда в тексте появляются двойные кавычки. Вылетает ошибка по SQL запросу. Пока решил проблему поменяв местами сами кавычки в коде в строках базовой модели.
Было: $arrayForSet[] = $field . ‘ = » ‘ . $this->$field . » ‘ «;
Стало: $arrayForSet[] = $field . » = ‘ » . $this->$field .’ » ‘;
Но учтите, это просто костыль. Если в тексте появятся одинарные кавычки, будут ошибки. Нужно ескепить их, но для PDO не силен.
При выполнении в index.php вылезает 404 ошибка:
$router = new router();
$router->setPath(SITE_PATH.’controllers’);
$router->start()