Тут такое дело, зарождается ещё один фреймвёрк, и думаю многих он заинтересует, ибо легковесных фреймвёрков под 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 — лишь обёртка
Выводы
Я конечно не надеюсь, что вы присоединитесь к разработке, но я искренне верю, что вам пригодится сам фреймвёрк, возможно его код или идеи из него :)
Если интересно — присоединяйтесь к группе в телеграм ;)
Я тоже сторонник идеи фреймворка, продиктованного конкретными задачами. без лишних монструозностей, которые могут и не понадобиться. И не имеет значения, откуда заимствованы идеи или куски кода – важен результат и полезность для автора. В коде с интересом покопаюсь :)
php 5.4 старье давай досвидания… я понимаю, что он вроде как легковесный, но pdo…. имхо объектную вещь надо, а не только нативные sql, плюс вопрос по поводу preInsert и preUpdate, не логичней бы было обозвать before? и объединить в beforeSave, да да, сперто с yii, но идея хороша, а внутри уже делать проверку на то новая запись или же идет апдейт. а то так можно и запутаться + дублирование кода, к примеру логгирование чего либо, придется писать метод, который в обеих pre вызывать, а вообще очень даже радует, namespace, простота, есть куда развиваться.
P.S. насчет контроллеров непривычно, но идея в целом понравилась, осталось привыкнуть. а непривычно потому что всегда мысль что контроллер это класс, а не функция в файле)
P.P.S. валидация планируется в моделях?
Да, планируется, уже сейчас Row класс требует декларации полей, добавить туда параметры валидации, и будет уже что-то похожее на Symfony/ZF2 Forms
Нет, нет, нет и ещё раз нет. Вы только представьте: такой легковесный и гибкий фреймворк, а Вы предлагаете встроить туда танк-паровоз из объектной прослойки на реляционную БД.
Я даже не вижу смысла в использовании PDO в таком фреймвёрке. В таких фреймворках хочется использовать всю силу отдельных типов БД без всяких прослоек.
подключение с помощью composer планируется?
Когда появятся зависимости – обязательно.
Получилось весьма интересно, обязательно попробую.
Ещё бы посмотреть насколько он быстр относительно других микрофреймворков – silex, slim и прочих.
Да, не думаю что фишка этого фрЭймвОрка (к Антохе: почему не е и ё, не понятно…) в том что было сделано под концретные задачи а именно для нагруженных проектов. Так что не думаю что есть смысл в сравнении с чем то. Да и кстати, уверен что Антон не стал бы ваять велосипед без особой надобности, если конечно кто то не решил оплатить создание оного.
Надеюсь нагруженный Сайт уже запущен и работает в данный момент, а этот фрэймворк не просто сделан на будущее или выкинут за ненужностью в паблик.
Я яросный сторонник yii framework :)
Прикольный фрейм, жду новую версию, хочу пощупать, пока он вызывает лишь любопытство, но не более.
P.S. ЯросТь
Советую посмотреть на фреймворк http://laravel.com/, особенно на его идею бандлов. Сам недавно наткнулся на него в поисках идей для микрофреймворка и нашёл в нём практически всё что хотел писать :(
Поделюсь своей разработкой
Вот ссылки
github.com/Alex014.RC
rc-php-framework.blogspot.com
Подскажите, почему требования PHP 5.4?
Для анонимных функций достаточно 5.3, или есть какая-то еще особенность?
А так спасибо, выглядит занятно.
Поставил себе в планах разобраться в нем.
понял, trait, сорри за глупый вопрос….
При попытке установить skeleton как написано в README, получил вот это:
Script sh ./bin/install.sh handling the post-install-cmd event returned with an error: ./bin/install.sh: 9: ./bin/install.sh: Bad substitution
./bin/install.sh: 9: ./bin/install.sh: realpath: not found
chmod: невозможно получить доступ к «/data/cache/»: Нет такого файла или каталога
chmod: невозможно получить доступ к «/data/logs/»: Нет такого файла или каталога
chmod: невозможно получить доступ к «/data/sessions/»: Нет такого файла или каталога
chmod: невозможно получить доступ к «/data/uploads/»: Нет такого файла или каталога
cp: не удалось выполнить stat для «/application/configs/app.dev.sample.php»: Нет такого файла или каталога
cp: не удалось выполнить stat для «/public/.htaccess.dev.sample»: Нет такого файла или каталога
Наверное сюда писать не нужно об этом, скажите куда писать.
Я тут пытаюсь запустить у себя всё это дело, но пока вот сталкиваюсь с ошибками. Первую просто вручную исправил, теперь вот:
Call to a member function getIdentity() on a non-object
/home/sid/www/bluz/library/bluzphp/framework/src/Bluz/View/Helper/User.php#39
Оказалось, что проект на гитхабе мигрировал, а его вики нет. Вики нашёл по старой ссылке.