Silex — микрофреймворк от создателей Symfony2

:

Почти год назад я опубликовал статью о микрофреймворке под названием 'fat-free', написанном на PHP. Тогда этот фреймворк и сама статья вызвали некоторый интерес, поэтому я решил сделать обзор еще одного PHP микрофреймворка в стиле популярного Sinatra — Silex project.
image
Созданный в известной в РНР кругах Sensio Labs, не менее известным Fabien Potencier — автором одного из самых популярных на сегодня PHP фреймворков — Symfony, Silex является облегченной версией ожидаемого армией фанатов (к которым осмелюсь отнести и себя) Symfony2.

Для своей работы Silex использует ключевые компоненты Symfony2 в связке с несложной реализацией шаблона проектирования “Внедрение зависимостей” в виде сервис-контейнера Pimple, который позволяет максимально просто отделить логические части кода друг от друга — сделать их независимыми.

Как и у Symfony2 — у Silex интуитивно понятный API, что делает процесс разработки достаточно приятным и позволяет практически в несколько шагов добавлять свой функционал в сам фреймворк.

Пример приложения


Простейшее приложение на Silex выглядит так:
require_once __DIR__.'/silex.phar'; // *.phar - одно из новшеств стандартного дистрибутива PHP 5.3. Фактически, это исполняемый архив (помните *jar в Java?).

$app = new Silex\Application(); // Еще одно из важных нововведений в PHP 5.3 — пространства имен. В данной строчке мы создаем инстанс приложения.

$app->get('/hello/{name}', function($name) { // Одна из самых ключевых особенностей фреймворка — присваивание контроллеров конкретным роутам.
    return "Hello $name";
});

$app->run(); // Запуск приложения

Как видите — все очень просто. Если пользователь сделает GET запрос на /hello/{name} — выполнится код внутри функции замыкания.

Установка


Для работы фреймворка понадобится PHP версии не ниже 5.3 с установленными в php.ini

phar.readonly = Off
phar.require_hash = Off .

Установка фреймворка сводится к загрузке phar-архива и подключении его в нашем bootstrap файле (index.php), как показано в примере выше.
Стоит упомянуть, что все запросы нужно перенаправлять именно на этот файл.
Если Вы используете Apache — создайте .htaccess с таким содержимым в корневой директории, рядом с index.php:

<IfModule mod_rewrite.c>
RewriteEngine On
#RewriteBase /path/to/app
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

Маршрутизация


Silex позволяет принимать маршруты неограниченной длины:
$app->get('/hello/awesome/pink/ponnies', function(){
...
});

В маршрутах можно использовать переменные:

$app->get('/hello/awesome/pink/{animal}', function($animal)  {
...
}); 

Неограниченное количество переменных:

$app->get('/hello/{impression}/{color}/{animal}', function($impression, $color, $animal) {
...
});

Запросы, конечно, могут быть и POST:

$app->post('/ponnies', function() use ($app) { // обратите внимание, что объект $app для дальнейшего использования в контроллере нужно передать внутрь замыкания
    $request = $app['request'];
	echo $request->get('ponny');
}

И PUT:

$app->put('/blog', function() {
    ...
}); 

И DELETE:

$app->delete('/blog', function() {
    ...
});

К каждому маршруту можно прицепить цепочку валидаторов:

$app->get('/blog/show/{postId}/{commentId}', function($postId, $commentId) {
    ...
})
->assert('postId', '\d+') // только цифры
->assert('commentId', '\d+'); // только цифры

А также присвоить название:

$app->get('/', function() {
    ...
})
->bind('homepage');

что пригодится для генерации ссылок на эти маршруты.

Перед и после каждого запроса можно исполнять произвольный код с помощью соответствующих before/after фильтров:

$app->before(function() {
    // перед
});

$app->after(function() {
    // после
});

Сервисы


Реализация “Внедрения зависимостей” в виде Pimple является достаточно простой и понятной.

Создаем новый инстанс приложения:

use Silex\Application;
$app = new Application();

и обращаемся к нему как к массиву, присваивая как обычные переменные:

$app['some_parameter'] = 'value';

так и уже привычные замыкания:

$app['some_service'] = function() {
    return new Service();
};

Для дальнейшего их использования, достаточно к ним обратиться как к элементам массива:

$service = $app['some_service'];

Если же сервис должен быть создан в едином экземпляре, используем метод share приложения:

$app['some_service'] = $app->share(function() {
    return new Service();
});

В таком случае $app['some_service'] будет создан только один раз при вызове, а при последующих вызовах будет возвращаться его инстанс.

Расширения


В фреймворке реализована гибкая система расширений с возможностью написания собственных.
Пример подключения и использования надуманного расширения для работы с базой данных:
use Acme\DatabaseExtension;

$app = new Application();

$app->register(new DatabaseExtension(), array(
    'database.dsn'      => 'mysql:host=localhost;dbname=myapp',
    'database.user'     => 'root',
    'database.password' => 'secret_root_password',
));

Из стандартных расширений сейчас доступны:

  • MonologExtension — логгер
  • SessionExtension — управление сессиями
  • TwigExtension — шаблонизатор
  • UrlGeneratorExtension — генерация URL

На подходе — Doctrine2 и генератор админки.

И это только начало. Адаптация сторонних библиотек в качестве расширений для Silex достаточно несложная, поэтому как только образуется сообщество вокруг этого фреймворка — их станет много.

Итоги


Микрофреймворки всегда будут занимать прочное место в создании веб приложений с несложной структурой, а выход микрофреймворка, базирующегося на плечах такого гиганта, как Symfony2 — безусловно очень важное событие в мире PHP.

Сайт фреймворка: http://silex-project.org

Полезные ссылки:

Сайт Symfony2
Документация Phar
Внедрение зависимостей