Silex — это микро PHP-фреймворк основанный на компонентах от Symfony.
В этой статье мы начнем с основ и попытаемся понять, для чего же нужен этот фреймворк.
Установка
Проще всего установить его через
composer:
{
"require": {
"silex/silex": "1.3.*@dev",
"twig/twig": "1.17.*@dev"
},
"require-dev": {
"symfony/var-dumper": "dev-master"
}
}
Или можете скачать
архив.
Чтобы установить зависимости и сгенерировать файл автозагрузки запустите:
$ composer update
Мы установим шаблонизатор
twig и дебаг-инструмент
var dumper которые используются в Symfony.
Создаем структуру проекта
Одна из причин, по которой мне нравится Silex — это то, что вы можете организовать структуру как вы захотите.
|-app/
|----config/
|-resources/
|----views/
|----logs/
|-src/
|----MyApp/
|-public/
|----index.php
|----.htaccess
|-vendor/
|-composer.json
Добавим в
public/index.php следющий код:
// public/index.php
<?php
require_once __DIR__ . '/../vendor/autoload.php';
$app = new Silex\Application();
$app->run();
Здесь мы создаем экземпляр класса Silex\Application и запускаем наше приложение.
Теперь если вы зайдете на сайт, то увидите сообщение об ошибке. Включим режим дебага в приложении:
$app['debug'] = true;
$app->run();
Снова перейдем на наш сайт и увидим
NotFoundHttpException, потому что у нас еще нету роутов.
Роутинг
Регистрация маршрутов в Silex очень проста, нам нужно только добавить url и кэллбек функцию:
// public/index.php
$app->get('/', function(){
return "Hello world";
});
Нам доступны
get, post, put, delete методы. Запрос может возвращать строку или экземпляр класса
Symfony\Component\HttpFoundation\Response:
// public/index.php
$app->get('/', function(){
return new Symfony\Component\HttpFoundation\Response("Hello world");
});
Параметры запроса
$app->get("/users/{id}", function($id){
return "User - {$id}";
});
Вы можете использовать и несколько параметров в запросе, но только при условии, что они будут переданы как параметры в функцию с такими же именами, иначе вы получите ошибку. Вы так же можете фильтровать параметры и ставить им значения по умолчанию:
$app->get("/users/{id}", function($id){
return "User - {$id}";
})
->value("id", 0) // значение по умолчанию
->assert("id", "\d+"); // id может быть только числом
Одна из моих любимых функций —
convert: она позволяет нам перехватить запрос и изменить значение, перед тем как вернуть его в функции:
$app->get("/users/{user}", function($user){
// return the user profile
return "User {$user}";
})->convert("user", function($id){
$userRepo = new User();
$user = $userRepo->find($id);
if(!$user){
return new Response("User #{$id} not found.", 404);
}
return $user;
});
В этом примере
convert берет id пользователя и ищет его в базе данных, а если его нет — то возвращает ошибку 404.
Если Вы фанат Laravel, то наверняка вы привыкли к фильтрам:
auth,
csrf и
guest. В Silex вы можете заставить анонимную функцию вести себя как фильтр:
$app->get("/users/{user}", function($user){
// показываем профиль
return "User {$user}";
})->before(function($request, $app){
// редирект если пользователь не вошел
})
->after(function($request, $response){
// записываем логи запроса
})
->finish(function(){
// записываем лог запроса
});
Имена для роутов
Когда в нашем приложении много роутов, то неплохо бы было давать им имена, для того чтобы было проще генерировать URL:
$app->get("/users/list", function(Silex\Application $app){
return "List of users";
})->bind('users');
<a href="{{ app.url_generator.generate('users') }}">Users</a>
Контроллеры
Одним из основных преимуществ использования контроллеров в является возможность их группировки. При создании RESTful API, URL, будет что-то вроде этого:
- /users
- /users/id (PUT, DELETE)
- /users/id/edit
В данном случае — лучшим решением будет создание сервиса для контроллеров, где они будут сгрупированны:
// src/MyApp/Controller/Provider/User.php
class User implements ControllerProviderInterface{
public function connect(Application $app)
{
$users = $app["controllers_factory"];
$users->get("/", "MyApp\\Controller\\UserController::index");
$users->post("/", "MyApp\\Controller\\UserController::store");
$users->get("/{id}", "MyApp\\Controller\\UserController::show");
$users->get("/edit/{id}", "MyApp\\Controller\\UserController::edit");
$users->put("/{id}", "MyApp\\Controller\\UserController::update");
$users->delete("/{id}", "MyApp\\Controller\\UserController::destroy");
return $users;
}
}
$app['controllers_factory'] возвращает нам экземпляр
Silex\ControllerCollection
который содержит нашу коллекцию роутов. В нашем котроллере все будет выглядеть так:
// src/MyApp/Controller/UserController.php
class UserController{
public function index(){
// show the list of users
}
public function edit($id){
// show edit form
}
public function show($id){
// show the user #id
}
public function store(){
// create a new user, using POST method
}
public function update($id){
// update the user #id, using PUT method
}
public function destroy($id){
// delete the user #id, using DELETE method
}
}
Осталось только добавить контроллер в наше приложение:
// app/routes.php
$app->mount("/users", new \MyApp\Controller\Provider\User());
В коллекции мы так же можем использовать фильтры:
// src/MyApp/Controller/Provider/User.php
class User implements ControllerProviderInterface{
public function connect(Application $app)
{
//...
$users->before(function(){
// check for something here
});
}
}
Провайдеры
Провайдер — «поставщики услуг» для нашего приложения. Создадим файл providers.php и добавим в него:
// app/providers.php
$app->register(new Silex\Provider\TwigServiceProvider(), array(
'twig.path' => __DIR__.'/../views',
));
Теперь мы можем использовать Twig:
$app->get(function(){
return $app['twig']->render('home.twig');
});
Заключение
Silex это маленький Symfony. Надеюсь, что эта статья направит вас в правильное русло. Мы не охватили все, но надеюсь я дал Вам понять, как работает этот фреймворк. \
комментарии (0)