Статьи

Введение в Silex – Микро-фреймворк Symfony

Silex – это микро-фреймворк PHP, основанный на компонентах Symfony и созданный на основе фреймворка Sinatra Ruby. В этой статье мы начнем с фреймворка и посмотрим, как он соответствует нашим потребностям.

Logo

Установка

Лучший и рекомендуемый способ установки Silex – через композитор:

// composer.json
{
    "require": {
        "silex/silex": "1.3.*@dev",
        "twig/twig": "1.17.*@dev"
    },
    "require-dev": {
        "symfony/var-dumper": "dev-master"
    }
}

Запустите composer update --dev Нам также потребовалась twigvar-dumperздесь

Создание структуры папок

Одна из вещей, которые мне нравятся в Silex, это то, что он дает вам простую структуру, которую вы можете организовать любым удобным для вас способом.

 |-app/
|----config/
|-resources/
|----views/
|----logs/
|-src/
|----MyApp/
|-public/
|----index.php
|----.htaccess
|-vendor/
|-composer.json

Например, мне не нравится, чтобы моя корневая папка приложения называлась webpublic В каталоге src

Наш файл public/index.phpSilex\Application

 // public/index.php
<?php

require_once __DIR__ . '/../vendor/autoload.php';

$app = new Silex\Application();

$app->run();

Теперь, если вы нажмете URL-адрес вашего корневого приложения, вы должны увидеть страницу не найдена . Вы можете включить отладку, установив для режима debugtrue

Если у вас возникли проблемы с доступом к вашим маршрутам, убедитесь, что корневой каталог вашего сервера указывает на общую папку. Вы можете проверить документацию для получения дополнительной информации о настройке вашего веб-сервера.

 // public/index.php

//...

$app['debug'] = true;

$app->run();

Теперь, если мы попробуем снова, мы получим описательное NotFoundHttpException

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

Регистрация маршрута проста: вы просто сопоставляете шаблон URL с функцией контроллера.

 // public/index.php
$app->get('/', function(){
	return "Hello world";
});

Мы можем обрабатывать getpostputdeletematch Функция 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, используя метод assertvalue

 $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, вы привыкли к таким фильтрам, как authcsrfguest Однако в 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
});

Точно так же вы можете использовать методы afterfinish Но имейте в виду, что метод finishrequestresponse

Названные маршруты

При работе с несколькими маршрутами имеет смысл называть их описательно. Это может быть полезно при обновлении формата 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

Действительно чистый способ справиться с этим – сгруппировать контроллеры в так называемые провайдеры контроллеров. Наш поставщик UserControllerProviderInterfaceconnect

 // 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());

Метод mountUser

Кроме того, одним из преимуществ использования наборов контроллеров является возможность использовать фильтры beforeafterfinish

 // 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::registerTwig_Environment

 $app->get(function(){
   return $app['twig']->render('home.twig');
});

Чтобы создать свой собственный провайдер для Silex, вам нужно реализовать Silex\ServiceProviderInterfaceregister Вы можете прочитать больше в документе .

Вывод

Silex – это небольшой и быстрый фреймворк для фанатов Symfony. Это введение нацелено на то, чтобы вы были на борту и опробовали основы. Мы не охватили все, но, надеюсь, я смогу заставить вас взволноваться, чтобы попробовать. Если у вас есть какие-либо вопросы или мнения, дайте мне знать в комментариях!