PHP Framework Bluz // PHP
Тут такое дело, зарождается ещё один фреймвёрк, и думаю многих он заинтересует, ибо легковесных фреймвёрков под PHP 5.4 не так уж и много :)
Почему рождается новый «велосипед» — да старый уже ж не в пору и скрипит
Чтобы не листать весь пост, вот вам ссылка на GitHub — https://github.com/bluzphp
В чем его удобство
Во-первых, следование заветам usability кода, за чем я старался следить.
Во-вторых, это отказ от какой-либо совместимости со старыми версиями PHP (устарел, давай, до свидания).
В-третьих, этот фреймвёрк создаётся как и положено — исходя из требований проекта, т.е. он выращен не искусственно под лозунгами «шоб було», а под реальные задачи, которые появлялись в проекте
Особенности
Поскольку фреймвёрк создавался под нужды проекта, то именно этим фактором обусловлено большинство принятых решений. В частности достаточно специфичный ACL, да и прикрученный twitter bootstrap из коробки тоже оттель.
Так же упомяну, что данный фреймвёрк начал проклёвываться ещё год назад в одном высокогонагруженном проекте, и о нём я еще расскажу на ThinkPHP ;)
Так что же внутри? А внутри всё пляшет от Application, который отвечает чуть меньше, чем за всё и с десяток пакетов, которые обеспечивают комфортную и быструю разработку приложений
MVC
Куда уж без него, но в нашей реализации есть военная хитрость, вот к примеру контроллер:
<?php return /** * @privelege View User Profile * @cache 5 minutes * @param integer $id * @return closure */ function($id) use ($view) { /** * @var View $view */ $view->user = $app->getDb()->fetchObject( "SELECT * FROM users WHERE id = ?", array($id), 'Users\Row'); };
Без паники, да action не предусмотрены, лишь модули и контроллеры-замыкания, и да — это упрощает разработку. Внимательный читатель уже заметит как контроллер «ловит» входные параметры, и что у него оказывается уже есть кеширование, и описана какая-то привилегия — да, всё это работает, как и задумывалось ;)
Идём дальше, возможно вы уже знаете, что я приверженец нативных шаблонизаторов, посему и в данном фремвёрке используется такой же:
return /** * @var Bluz\View $view * @return closure */ function() use ($view) { $view->title = "Hello world" };
Собственно код шаблона:
<h2><?=$title?></h2> <!-- так тоже работает --> <h2><?=$this->title?></h2>
Всякие мелкие фишки по работе с шаблонизатором описаны в соответствующем разделе wiki
База данных
Для работы с базой данных предусмотрен пакет Db (оригинально то как), он включает в себя Db\Db, Db\Table и Db\Row. Класс Db представляет из себя лишь обёртку над PDO, и слегка упрощает нам жизнь:
<?php // init settings $db->setConnect(array( 'type' => 'mysql', 'host' => 'localhost', 'name' => 'db name', 'user' => 'root', 'pass' => '' )); // quote variable $db->quote($id) // query $db->query("SET NAMES 'utf8'"); // get one $db->fetchOne("SELECT COUNT(*) FROM users"); // get row $db->fetchRow("SELECT * FROM users WHERE id = :id", array(':id'=>$id)); // get array $db->fetchAll("SELECT * FROM users WHERE ip = ?", array($ip)); // get pairs $pairs = $db->fetchPairs("SELECT ip, COUNT(id) FROM users GROUP BY ip", array()); // get object // .. to stdClass $stdClass = $db->fetchObject('SELECT * FROM some_table WHERE id = ?', array($id)); // .. to new Some object $someClass = $db->fetchObject('SELECT * FROM some_table WHERE id = ?', array($id), 'Some'); // .. to exists instance of Some object $someClass = $db->fetchObject('SELECT * FROM some_table WHERE id = ?', array($id), $someClass); // plain insert/update/delete $db->insert('some_table', array('col1'=>'foo', 'col2'=>'bar')); $db->update('some_table', array('col1'=>'bar', 'col2'=>'foo'), array('id'=>1)); $db->delete('some_table', array('id'=>1));
О транзакциях тоже не забыл, вот пример контроллера:
if ($this->getDb()->transaction(function() { /** * @var \Bluz\Application $this */ $this->getDb()->delete('acl_privileges'); })) { $this->getMessages()->addSuccess('All data was saved'); } else { $this->getMessages()->addError('Internal server error'); }
Классы Table и Row это некое подобие active record:
<?php namespace Application\Users; class Row extends \Bluz\Db\Row { public function preInsert() { $this->created = gmdate('Y-m-d H:i:s'); } public function preUpdate() { $this->updated = gmdate('Y-m-d H:i:s'); } } $userRow = new \Application\Users\Row(); $userRow -> login = 'username'; $userRow -> save();
Роутеры
Просты до безобразия, указываются непосредственно в комментариях контроллера:
/** * @route /users/{$id} * @param integer $id */
При использование не требуют явного указания имени (привет ZF):
<?php $this->url('users', 'login'); $this->url('users', 'profile', array('id' => $id)); $this->url('pages', 'show', array('name' => $name)); ?>
Конечно, подобная реализация не без недостатков, но таки вполне юзабельно, и под стать фремвёрку.
Ещё
Есть еще пачка пакетов, пожалуй стоит привести их список:
- Acl — позволяет быстро и гибко организовать раздачу прав
- Cache — очень простая обёртка над memcached
- EventManager — события и их обработчики
- Registry — тут без комментариев
- Request — объект запроса, сам по себе используется редко
- Session — лишь обёртка
Выводы
Я конечно не надеюсь, что вы присоединитесь к разработке, но я искренне верю, что вам пригодится сам фреймвёрк, возможно его код или идеи из него :)
Если интересно — присоединяйтесь к Skype чату ;)