Adicione uma barra ao url antes de invocar o Silex

2

Como a maioria dos frameworks por aí, o Silex depende de regras de reescrita para lidar com URLs bonitas. O padrão .htaccess recomendado para uso com esta estrutura é

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

O que é simples e funciona bem. Mas se eu também quiser reescrever o pedido para sempre incluir uma barra no final eu não posso fazê-lo funcionar. Eu tentei usar as seguintes regras antes.

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]

Para depurar isso, tentei forçar um redirecionamento usando o [R] flag e posso ver que ele é avaliado corretamente, mas as duas regras juntas não fazem o truque, pois a solicitação resultante ainda permanece sem uma barra final.

Para resumir: example.com/foo deve redirecionar para example.com/foo/ e, no final, manipulado por index.php . example.com/foo/ deve ser tratado por index.php sem modificações.

Eu não sou especialista em mod_rewrite, mas passei um tempo significativo lendo os documentos aqui e tenho a sensação de que isso deve ser possível para resolver isso.

Obrigado antecipadamente, Alex

    
por Alex Kalyvitis 22.12.2012 / 13:08

1 resposta

1

Acontece que o apache e mod_rewrite estão realmente funcionando da maneira que deveriam, dada a configuração mostrada na pergunta. O framework php não estava fazendo uso do URL correto.

Ao usar o php com o apache, o apache cria diversas variáveis de servidor (ou seja, $_SERVER global).

Assim, considerando as regras de reescrita acima, quando um usuário navega para example.com/resource , o apache primeiro reescreveria para example.com/resource/ e, posteriormente, entregaria tudo para index.php para manipular. O que não era tão óbvio foi que a variável $_SERVER['REQUEST_URI'] não foi alterada, mas o $_SERVER['REDIRECT_URL'] estava sendo definido com o novo uri reescrito.

Assim, a questão de não redirecionar era, na verdade, a estrutura que nunca usou o novo global introduzido pelo apache. Para fazer uso dessa variável global, estenda o Silex/Application.php existente e sobrescreva seu método run() da seguinte forma:

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);
    }

}

Espero que isso ajude!

Alex

    
por 07.04.2013 / 09:53