Рассмотрим варианты организации route в Silex.
Первый Вариант.
самый простой, первым показан в документации Silex
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; $app->post('/feedback', function (Request $request) { $message = $request->get('message'); mail('feedback@yoursite.com', '[YourSite] Feedback', $message); return new Response('Thank you for your feedback!', 201); });
$app->post()
, также возможны варианты $app->get()
, $app->delete()
, $app->put()
, $app->match()
при данном варианте желательно дописывать ->method('PUT|POST')
Использование переменных
$app->get('/blog/{id}', function ($id) { ... });
Самый просто пример, мы единственное ожидаем любое значение id и метод GET.
$app->get('/blog/{postId}/{commentId}', function ($commentId, $postId) { ... }) ->assert('postId', '\d+') ->assert('commentId', '\d+');
Oтличается от предыдущего, только наличием нескольких переменных, но также ->assert('postId', '\d+')
указано что именно мы ожидаем в переменных а именно только цифры.
$app->get('/blog/{id}', function (Application $app, Request $request, $id) { ... }) ->value('id', 1);
На данном варианте показано что возможно кроме переменных передавать и в какой последовательности, ->value('id', 1);
уже указано значение по умолчанию, то есть мы можем ничего не передавать в запросе.
$app->get('/user/{id}', function ($id) { // ... }) ->convert('id', function ($id) { return (int) $id; }) ->bind('get_user'); $userProvider = function ($id) { return new User($id); }; $app->get('/user/{user}', function (User $user) { // ... })->convert('user', $userProvider);
Теперь мы еще добавили функционал который ->convert('id', function ($id) { return (int) $id; })
конвертирует данные которые приходят из запроса, а ->bind('get_user')
дает роуту название чтобы было возможно его использовать при генерации URL в PHP $app['url_generator']->generate('get_user')
и Twig {{ url('get_user', {'id': '1'}) }}
. Далее просто один из примеров конвертации приходящих данных.
плюсы:
- все просто, организовывается в одном файле
минусы:
- при разработке в группе возможны пересечения путей
- при расширении необходимо дописывать функционал пути в тот же файл
Второй Вариант.
Route организовывается также, единственное мы перенесем контролер в отдельный файл.
//routes.php $app->get('/', 'Controllers\Homepage::index'); //Controllers/Homepage.php namespace Controllers use Silex\Application; use Symfony\Component\HttpFoundation\Request; class Homepage { public function index(Request $request, Application $app) { ... } }
Этот вариант просто расширяет первый, тоесть возможно использовать все что есть в первом варианте.
плюсы:
- Все плюсы Первого варианта
- Вынесение Контролеров в отдельных файл, облегчает разработку
минусы:
- Все минусы первого варианта
Вариант Третий.
В данном случае мы создаем отдельно контролеры, и добавляем в общий роутер, этот случай мало отличается от Второго, но тут возможно разделение роутов, в разные файлы, просто при инициализации приложения, мы имеем возможность дописывать префикс чтобы было меньше пересечений.
$app['controllers_factory'] ->post('/home', 'Controllers\Homepage::index') ->bind("home_index"); $app->mount($prefix, $routes);
Использование переменных аналогично Первому случаю. Данный вариант аналогичен
use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; $routeCollection = new RouteCollection(); $route = new Route('/home', array('_controller' => 'Controllers\Homepage::index')); $route->setMethods('post'); $routeCollection->add('home_index', $route); $app['routes']->addCollection($routeCollection);
плюсы:
- все разделено, возможность разрабатывать независимые модули для приложения
минусы:
- При разработке командой, возможен порог для подключения нового участника(введение в архитектуру всего приложения)
Четвертый Вариант.
Такой вариант привычен разработчикам на Symfony 2. Поэтому если вы желаете его использовать то возможно вы выбрали не тот Framework для своего приложения.
use Symfony\Component\Config\FileLocator; use Symfony\Component\Routing\Loader\YamlFileLoader; use Symfony\Component\Routing\RouteCollection; use Silex\Application; $app = new Application(); $loader = new YamlFileLoader(new FileLocator(__DIR__ . '/сonfig')); $collection = $loader->load('routes.yml'); $app['routes']->addCollection($collection);
Мы вынесли все роутеры в отдельный файл routes.yml, есть варианты PhpFileLoader и XmlFileLoader.
# config/routes.yml home: path: / defaults: { _controller: 'Controllers\Homepage::index' } hello: path: /hello/{name}.{_format} defaults: { _controller: 'Controllers\Homepage::hello', name: 'andrey', _format: html } requirements: name: \w+ _format: html|rss methods: [POST] api: prefix: /api resource: api.yml # config/api.yml api.list: path: /list defaults: { _controller: 'Controllers\Api::list' }
Доступны все возможности как и в первых трех случаях, но они все вынесены в файл конфигурации. Подробнее можно узнать на сайте Symfony
<?php // Controllers/Homepage.php namespace Controllers; use Symfony\Component\HttpFoundation\Response; use Silex\Application; class Homepage { public function index() { return new Response("Homepage::index"); } public function hello(Application $app, $name) { return new Response("Hello" . $app->escape($name)); } }
плюсы:
- все разделено, возможность разрабатывать независимые модули для приложения
- все настройки routes в файле конфигов
минусы:
- Подключение дополнительных библиотек.
- Необходимость кешировать готовый функционал.
- нельзя использовать Route\SecurityTrait по умолчанию, прийдется писатьсвой загрузчик.
Выводы.
Есть много возможностей использование Route в Silex, Зависит от контекста задачи какой вам больше подходит в данном варианте.