Простой MVC-фреймворк для PHP 5.2
Иногда бывает необходимо быстро создать небольшой сайт, однако от удобств больших фреймворков отказываться не хочется. Вместе с тем, нет желания палить из пушки по воробью, устанавливая и настраивая несколько мегабайт кода для простых скриптов.
Вот тогда и возникает потребность в миниатюрном MVC-фреймворке, обладающем основными атрибутами старших собратьев.
Фреймворк Web2bb – как раз именно из таких. Началось все со статьи Кевина Ватерсона Model View Controller MVC на сайте phpro.org. В ней автор попытался создать простой каркас для PHP-приложений. Затем по многочисленным просьбам читателей фреймворк был доработан и немного усовершенствован. Фреймворк этот теперь называется web2bb. Многих, однако, не устроило основное требование фреймворка: PHP 5.3. Согласитесь, что до массового проникновения этой версии PHP ещё далековато…
Я взял на себя смелость переделать код под PHP 5.2. Впоследствии я также усовершенствовал фреймворк. По-моему получилось неплохо. Фреймворк обладает фантастической скоростью: даже не пытайтесь сравнивать его с другими MVC. Разница будет громадной. Таким образом, каркас подойдёт и для высоко-нагрузочных проектов, работающих на слабых или shared-серверах. А так как код достаточно простой, то любой опытный разработчик разберется с ним за час и в дальнейшем сможет переделать или доделать фреймворк под свои нужды.
Требования простые: необходим PHP 5.2.x, хотя возможна работа и под 5.1. Фреймворк использует ООП, авто-загрузку классов, отражатели (Reflections) и PDO в качестве движка для доступа к БД.
Проект доступен на Google Code по адресу web2bb-php52. Доступ к коду осуществляется только через SVN на странице source. В комплекте есть пример простого форума/блога с необходимым SQL.
Давайте посмотрим на пример кода:
Модель blogModel (/application/models/app/blogmodel.php) наследует dbAbstraction:
// model
class blogModel extends dbAbstraction {
private $db;
public function __construct() {
$this->db = db::getInstance(); // connect to database
}
public function getTopics($id=null) {
if($id) {
// get topic with id = $id
$sql = "SELECT * FROM topics WHERE id=:id";
$st = $this->db->prepare($sql);
$st->bindParam(":id", $id, PDO::PARAM_INT);
$st->execute();
$res = $st->fetch(PDO::FETCH_ASSOC);
} else {
// get all
$sql = "SELECT * FROM topics ORDER BY created DESC";
$res = $this->db->query($sql);
}
return $res;
}
// ...SKIP...
public function delComment($id) {
$topic_id = $this->field('comments',$id,'topic_id'); // get comment's topic_id
$this->delete('comments',$id); // delete comment
$this->inc('topics',$topic_id,'com_count',-1); // update comment count
return $topic_id;
}
}
Контроллер blogController (/application/modules/blog/controllers/blogcontroller.php) наследует baseController:
// controller
class blogController extends baseController implements IController {
public function __construct() {
parent::__construct();
$this->blog = new blogModel; // model
$this->module = 'blog'; // set current module for render method
$config = config::getInstance(); // get config data
$this->view->version = $config->config_values['application']['version']; // set view variable $version
}
public function index() {
$this->view->title = 'Blog';
$this->view->topics = $this->blog->getTopics();
// $this->layout=null; // no layout
$this->cache = true; // false by default
$this->render('index'); // render /modules/blog/views/index.phtml
}
public function add() {
if(!empty($_POST)) { // save data
$t = $_POST['topic'];
$t['created'] = date('Y-m-d H:i:s');
$this->blog->insert('topics',$t); // new topic
$this->redirect("/blog/"); // redirect to topics list
} else { // no data, render form
$this->view->title = 'new topic';
$this->render('add');
}
}
// ...SKIP...
public function delete($obj,$id=null) {
switch($obj) {
case 'topic':
$this->blog->delTopic($id);
$this->redirect("/blog/");
break;
case 'comment':
$tid = $this->blog->delComment($id); // and return topic_id for redirect
$this->redirect("/blog/view/".$tid);
break;
default:
exit;
}
}
}
Внешний шаблон (/application/layouts/index.phtml):
<!-- layout --> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title><?php echo $title; ?></title> <link rel="stylesheet" href="/css/style.css"> </head> <body> <h1><?php echo $title; ?></h1> <a href="/"><?php echo lang::__HOME; ?></a> | <a href="/blog"><?php echo lang::__BLOG; ?></a> | <a href="/contact"><?php echo lang::__CONTACT; ?></a><br/> <!-- $content is the page template --> <div id="content"><?php echo $content; ?></div> </body> </html>
Шаблон страницы /blog/index/ (/application/modules/blog/views/index.phtml):
<!-- index page template --> <h1><?php echo $heading; ?></h1> <p><?php echo $breadcrumbs ?></p> <table> <?php foreach ($topics as $topic ): ?> <tr> <td><?php echo $topic['id'] ?> (<a href="/blog/delete/topic/<?php echo $topic['id'] ?>/">del</a>)</td> <td><a href="/blog/view/<?php echo $topic['id'] ?>/"><?php echo $topic['title'] ?></a> (<?php echo $topic['com_count'] ?>)</td> <td><?php echo $topic['content'] ?></td> <td><?php echo $topic['author'] ?></td> <td><?php echo $topic['created'] ?></td> </tr> <?php endforeach; ?> </table> <a href="/blog/add/">new topic</a>
Ваши мысли в комментариях.
22.09.09 в 03:18
Очень Интересный вариант.
Скачал твой вариант для PHP5.2, всё работает кроме ссылки блог? В чем может быть загвоздка?
22.09.09 в 08:53
Чтобы блог работал, нужно создать БД из приложенного sql-файла, затем прописать настройки БД в конфигурационном файле.
24.09.09 в 00:39
Океан извинений – всё работает.
Вот только маленький вопрос меня терзает.
Кодировка БД UTF-8, а при кодировке сайта windows-1251 записи из БД не читаются. Где можно поправить кодировку? Плюс кодировку лучше задавать в конфиге.
24.09.09 в 07:46
Где вы нашли windows 1251? Там везде юникод. Кодировка базы в «\application\config\config.ini.php», кодировка html в «\application\layouts\index.phtml».
25.10.09 в 15:30
Интересный фреймворк. Только поигравшись с блогом заметил кривости в ссылках, лишние слеши приписываются…
27.10.09 в 21:16
а как скачать фреймворк? по ссылке автора пусто
27.10.09 в 23:42
Чтобы скачать, нужно установить систему управления версиями Subversion (TortoiseSVN, например, для Windows). Затем идем в раздел source и читаем инструкции.
16.12.09 в 21:47
интересно… MVC всегда смущал меня своей нагруженностью, а тут и размер и скорость действительно впечатляют. Поковыряюсь на досуге.
05.03.10 в 14:38
Я вот только одной задумки не понял…FrontController, View – это модели??? Нет.
В web2bb смешан фреймворк и CMS…у нас есть модули…почему бы не складывать в папки модулей модели, которые к нему относятся? /application/models/app это не практично.
Если убрать интерфейс из контроллера…то отражатели совершенно не нужны, просто лишний код…я их сразу убрал.
Вообще искал простой фреймворк около 3 месяцев, так ничего и не нашел….может стоит создать общество…создадим русский PHP фреймворк
Там поставить цель сделать удобный фреймворк размером 50-100кб не более
23.03.10 в 06:02
В сях, например, при хорошей структуре данных и подходящей архитектуре переход между модулями может сокращаться до нескольких инструкций процессора. PHP же интерпретируется и не очень «правильно» осуществляют переходы по модели mvc. т.е. он реально осуществляет переходы, а не использует подстановки. Да, обфускация кода можеть дать прирост скорости даже в разы, но пока мы работаем с пхп-шными классами классическое моделирование программы невозможно. Отсюда и появляется вся «грязь» языка php. Даже быстродействие программы может сильно варьироваться в зависимости от данных, что ставит под большое сомнение разработку универсальных фреймворков. Тоже самое относится и к реляционным базам данных (весь sql поголовно). Это в интерпрайзе всё просто – спрятал подноготную в ядро системы, а перед глазами гуй. Тут же большая часть красоты наводится руками, генераторы sql запросов – ещё одно убийство системы. Не пользуйтесь фреймворками вообще на больших проектах. Спасибо за внимание.
22.04.10 в 00:22
Абстракции и фреймворки гавно, чистый код рулит…это слова далеко не профессионала. Я тоже когда-то писал вот такие коменты, доказывая с пеной у рта что чистый код рулит.
Теперь я использую фреймворки, мне лень и жаль своего времени писать всякую муть. Считай я беру конструктор и собираю сайт, мне пофиг что упадет быстродействие в 2-3 раза…моё время намного дороже процессорного.
22.04.10 в 00:27
if($id) {
$sql = «SELECT * FROM topics WHERE id=:id»;
$st = $this->db->prepare($sql);
$st->bindParam(«:id», $id, PDO::PARAM_INT);
$st->execute();
return $st->fetch(PDO::FETCH_ASSOC);
}
$sql = «SELECT * FROM topics ORDER BY created DESC»;
return $this->db->query($sql);