Как и большинство других фреймворков, Silex зависит от правил перезаписи для обработки красивых URL-адресов. По умолчанию для этой платформы рекомендуется использовать .htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Это просто и прекрасно работает. Но если я также хочу переписать URI запроса, чтобы всегда включать косую черту в конце, я не могу заставить его работать. Раньше я пробовал использовать следующие правила.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(.*)/$
RewriteRule . %{REQUEST_URI}/ [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Чтобы отладить это, я попытался принудительно перенаправить с помощью [R]
flag, и я вижу, что он оценивается правильно, но оба правила вместе не работают, поскольку полученный uri запроса все еще остается без косой черты.
Подводить итоги: example.com/foo
следует перенаправить на example.com/foo/
и в конце концов обработал index.php
. example.com/foo/
должен обрабатываться index.php
без доработок.
Я не эксперт в mod_rewrite, но я потратил много времени на чтение документации. Вот и у меня есть интуиция, что эту проблему можно решить таким образом.
Заранее спасибо, Алекс
Оказывается, apache и mod_rewrite на самом деле работают так, как должны, учитывая настройку, показанную в вопросе. Фреймворк php не использовал правильный URL-адрес.
При использовании php с apache apache создает несколько переменных сервера (а именно $_SERVER
Глобальный).
Итак, учитывая приведенные выше правила перезаписи, когда пользователь переходит к example.com/resource
apache сначала перепишет на example.com/resource/
и впоследствии передать все index.php
обрабатывать. Что было не так очевидно, так это то, что $_SERVER['REQUEST_URI']
переменная не была изменена, скорее $_SERVER['REDIRECT_URL']
устанавливался с новым переписанным uri.
Таким образом, проблема отсутствия перенаправления на самом деле была в структуре, которая никогда не использовала новый глобал, представленный apache. Чтобы использовать эту глобальную переменную, расширьте существующий Silex/Application.php
и перезаписать его run()
метод так:
class Application extends Silex\Application
{
public function run(Request $request = null)
{
if (null === $request) {
if (isset($_SERVER['REDIRECT_URL'])) {
$_SERVER['REQUEST_URI'] = $_SERVER['REDIRECT_URL'];
}
$request = Request::createFromGlobals();
}
$response = $this->handle($request);
$response->send();
$this->terminate($request, $response);
}
}
Надеюсь это поможет!
Alex