Тут такое дело, зарождается ещё один фреймвёрк, и думаю многих он заинтересует, ибо легковесных фреймвёрков под PHP 5.4 не так уж и много :)
Почему рождается новый «велосипед» — да старый уже ж не в пору и скрипит
Чтобы не листать весь пост, вот вам ссылка на GitHub — https://github.com/bluzphp
В чем его удобство
Во-первых, следование заветам usability кода, за чем я старался следить.
Во-вторых, это отказ от какой-либо совместимости со старыми версиями PHP (устарел, давай, до свидания).
В-третьих, этот фреймвёрк создаётся как и положено — исходя из требований проекта, т.е. он выращен не искусственно под лозунгами «шоб було», а под реальные задачи, которые появлялись в проекте
Особенности
Поскольку фреймвёрк создавался под нужды проекта, то именно этим фактором обусловлено большинство принятых решений. В частности достаточно специфичный ACL, да и прикрученный twitter bootstrap из коробки тоже оттель.
Так же упомяну, что данный фреймвёрк начал проклёвываться ещё год назад в одном высокогонагруженном проекте, и о нём я еще расскажу на ThinkPHP ;)
Так что же внутри? А внутри всё пляшет от Application, который отвечает чуть меньше, чем за всё и с десяток пакетов, которые обеспечивают комфортную и быструю разработку приложений
MVC
Куда уж без него, но в нашей реализации есть военная хитрость, вот к примеру контроллер:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | <?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 не предусмотрены, лишь модули и контроллеры-замыкания, и да — это упрощает разработку. Внимательный читатель уже заметит как контроллер «ловит» входные параметры, и что у него оказывается уже есть кеширование, и описана какая-то привилегия — да, всё это работает, как и задумывалось ;)
Идём дальше, возможно вы уже знаете, что я приверженец нативных шаблонизаторов, посему и в данном фремвёрке используется такой же:
1 2 3 4 5 6 7 8 | return /** * @var Bluz\View $view * @return closure */ function () use ( $view ) { $view ->title = "Hello world" }; |
Собственно код шаблона:
1 2 3 | <h2><?= $title ?></h2> <!-- так тоже работает --> <h2><?= $this ->title?></h2> |
Всякие мелкие фишки по работе с шаблонизатором описаны в соответствующем разделе wiki
База данных
Для работы с базой данных предусмотрен пакет Db (оригинально то как), он включает в себя Db\Db, Db\Table и Db\Row. Класс Db представляет из себя лишь обёртку над PDO, и слегка упрощает нам жизнь:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <?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)); |
О транзакциях тоже не забыл, вот пример контроллера:
01 02 03 04 05 06 07 08 09 10 | 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:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | <?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(); |
Роутеры
Просты до безобразия, указываются непосредственно в комментариях контроллера:
1 2 3 4 | /** * @route /users/{$id} * @param integer $id */ |
При использование не требуют явного указания имени (привет ZF):
1 2 3 4 5 | <?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
Оказалось, что проект на гитхабе мигрировал, а его вики нет. Вики нашёл по старой ссылке.