Silex — это микро-фреймворк PHP, основанный на компонентах Symfony и созданный на основе фреймворка Sinatra Ruby. В этой статье мы начнем с фреймворка и посмотрим, как он соответствует нашим потребностям.
Установка
Лучший и рекомендуемый способ установки Silex — через композитор:
// composer.json
{
"require": {
"silex/silex": "1.3.*@dev",
"twig/twig": "1.17.*@dev"
},
"require-dev": {
"symfony/var-dumper": "dev-master"
}
}
Запустите composer update --dev
Нам также потребовалась twig
var-dumper
здесь
Создание структуры папок
Одна из вещей, которые мне нравятся в Silex, это то, что он дает вам простую структуру, которую вы можете организовать любым удобным для вас способом.
|-app/
|----config/
|-resources/
|----views/
|----logs/
|-src/
|----MyApp/
|-public/
|----index.php
|----.htaccess
|-vendor/
|-composer.json
Например, мне не нравится, чтобы моя корневая папка приложения называлась web
public
В каталоге src
Наш файл public/index.php
Silex\Application
// public/index.php
<?php
require_once __DIR__ . '/../vendor/autoload.php';
$app = new Silex\Application();
$app->run();
Теперь, если вы нажмете URL-адрес вашего корневого приложения, вы должны увидеть страницу не найдена . Вы можете включить отладку, установив для режима debug
true
Если у вас возникли проблемы с доступом к вашим маршрутам, убедитесь, что корневой каталог вашего сервера указывает на общую папку. Вы можете проверить документацию для получения дополнительной информации о настройке вашего веб-сервера.
// public/index.php
//...
$app['debug'] = true;
$app->run();
Теперь, если мы попробуем снова, мы получим описательное NotFoundHttpException
Маршрутизация
Регистрация маршрута проста: вы просто сопоставляете шаблон URL с функцией контроллера.
// public/index.php
$app->get('/', function(){
return "Hello world";
});
Мы можем обрабатывать get
post
put
delete
match
Функция handle должна возвращать либо строку, либо экземпляр 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}";
});
Мы можем добавить несколько параметров в шаблон URL, единственное соглашение состоит в том, что имя параметра шаблона URL должно совпадать с именем, используемым в функции, иначе вы получите RuntimeException
Вы также можете указать шаблон URL, используя метод assert
value
$app->get("/users/{id}", function($id){
return "User - {$id}";
})
->value("id", 0) //set a default value
->assert("id", "\d+"); // make sure the id is numeric
Один из моих любимых методов маршрутизации — 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
Ответ 404 возвращается, если пользователь не найден.
Если вы поклонник Laravel, вы привыкли к таким фильтрам, как auth
csrf
guest
Однако в Silex вы можете предоставить функцию обратного вызова, которая будет вести себя как фильтр.
$app->get("/users/{user}", function($user){
// return the user profile
return "User {$user}";
})->before(function($request, $app){
// redirect if the user is not logged in
})
->after(function($request, $response){
// log request events
})
->finish(function(){
// log request event
});
Точно так же вы можете использовать методы after
finish
Но имейте в виду, что метод finish
request
response
Названные маршруты
При работе с несколькими маршрутами имеет смысл называть их описательно. Это может быть полезно при обновлении формата URL или создании шаблонных ссылок.
$app->get("/users/list", function(Silex\Application $app){
return "List of users";
})->bind('users');
Если вы используете поставщика услуг генератора URL , вы можете создать ссылку непосредственно на маршрут.
<a href="{{ app.url_generator.generate('users') }}">Users</a>
Контроллеры
В реальных приложениях мы не используем замыкания для маршрутизации, а создаем отдельные классы контроллеров для обработки запросов.
$app->get("/", "MyApp\Controller\HomeController::index");
Группировка контроллеров
Одним из основных преимуществ использования контроллеров классов является возможность их группировки. При создании RESTful API URL-адреса будут выглядеть примерно так:
-
/users
-
/users/id
-
/users/id/edit
Действительно чистый способ справиться с этим — сгруппировать контроллеры в так называемые провайдеры контроллеров. Наш поставщик User
ControllerProviderInterface
connect
// 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
UserController
// 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
}
}
Единственная оставшаяся часть — это присоединение нашей коллекции контроллеров к нашему приложению. При работе с маршрутами я предпочитаю подход Laravel — регистрировать их в отдельном файле и включать их.
// app/routes.php
$app->mount("/users", new \MyApp\Controller\Provider\User());
Метод mount
User
Кроме того, одним из преимуществ использования наборов контроллеров является возможность использовать фильтры before
after
finish
// src/MyApp/Controller/Provider/User.php
class User implements ControllerProviderInterface{
public function connect(Application $app)
{
//...
$users->before(function(){
// check for something here
});
}
}
Провайдеры
Мы упоминали этот термин ранее, но он просто означает небольшой класс, который связывает компонент с приложением Silex. Существует список предварительно включенных поставщиков, и для его использования вы просто регистрируете его в экземпляре приложения.
// app/providers.php
$app->register(new Silex\Provider\TwigServiceProvider(), array(
'twig.path' => __DIR__.'/../views',
));
Конечно, это должно быть сделано после того, как вам понадобится Twig внутри вашего композера и обновите зависимости. Теперь, если вы посетите метод TwigServiceProvider::register
Twig_Environment
$app->get(function(){
return $app['twig']->render('home.twig');
});
Чтобы создать свой собственный провайдер для Silex, вам нужно реализовать Silex\ServiceProviderInterface
register
Вы можете прочитать больше в документе .
Вывод
Silex — это небольшой и быстрый фреймворк для фанатов Symfony. Это введение нацелено на то, чтобы вы были на борту и опробовали основы. Мы не охватили все, но, надеюсь, я смогу заставить вас взволноваться, чтобы попробовать. Если у вас есть какие-либо вопросы или мнения, дайте мне знать в комментариях!