Если вы делаете более-менее серьезное веб-приложение на symfony, стоит задуматься о том, как вы будете предоставлять доступ до админки вашего проекта. Стандартный раутинг бэкенда, или любого другого вторичного приложения, может привести к недоумению неискушенного пользователя. Клиенты не привыкли видеть в строке адреса http://mysite.ru/backend.php/posts/. Да и вообще эстетической красоты урлов ради, стоит подумать о методах облагораживания ссылок.
Раутинг с использованием субдомена
Ресурс symfony-check.org предлагает решить проблему следующим тривиальным способом.
Добавить в конфигурацию виртуального хоста директиву
ServerAlias admin.mysite.ru
или другим способом заставить веб сервер отвечать по субдомену.
Добавить в .htaccess рерайт по префиксу "admin." на backend.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} ^admin\..*
RewriteRule ^(.*)$ backend.php [QSA,L]
поправить настройки в apps/backend/config/settings.yml
prod:
.settings:
no_script_name: true
и почистить кеш
php symfony cc
Таким образом, мы без особых усилий получим реально красивые урлы. Какие недостатки есть у этого способа? При генерации урлов из бэкенда, используя cross-application routing, мы должны генерить абсолютные урлы с именем домена фронта. Для этого можно, например, хранить имя домена где-то в конфиге.
Раутинг с использованием подпапки
Лично мне больше нравится, когда админку можно обнаружить в сабфолдере /admin/. Поэтому я начал думать как лучше реализовать это решение.
Первое что надо сделать — добавить правила в .htaccess
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/admin(/?|/.*$)
RewriteRule ^(.*)$ backend.php [QSA,L]
и, также как и в прошлом способе, поправить apps/backend/config/settings.yml
prod:
.settings:
no_script_name: true
Далее надо как-то заставить экземпляры раутинга работать с подпапкой. Сначала в голову пришла идея добавить префикс /admin/ всем экземплярам.
Проблема в том, что невсегда разработчики плагинов дают возможность редактирования своих раутингов. Таким образом, наиболее очевидный вариант не подходит, если вы планируете использовать множество плагинов.
Я долго думал как справиться с этой проблемой. В результате решение нашел на одном из блогов.
Автор предлагает наследовать класс управления раутингов symfony. Правда используя его код, я так и не смог добиться нормальных результатов в dev среде. Так что привожу измененный код, который работает у меня.
class sfBackendRouting extends sfPatternRouting
{
public function initialize(sfEventDispatcher $dispatcher, sfCache $cache = null, $options = array())
{
$options['context']['prefix'] .= isset($options['prefix']) ? $options['prefix'] : '';
parent::initialize($dispatcher, $cache, $options);
}
public function getRouteThatMatchesUrl($url)
{
if(isset($this->options['prefix']))
{
if(strpos($url, $this->options['prefix']) === 0)
$url = substr($url, strlen($this->options['prefix']));
else
return false;
}
if($url == '')
{
$url = '/';
}
return parent::getRouteThatMatchesUrl($url);
}
}
Далее надо поправить конфиг apps/backend/config/factories.yml
all:
routing:
class: sfBackendRouting
param:
generate_shortest_url: true
extra_parameters_as_query_string: true
prefix: /admin
Чистим кеш
php symfony cc
и voil? — наш бэкенд теперь отвечает по подпапке.
