Простой 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>
Ваши мысли в комментариях.