Url mudando com htaccess
Tenho uma apresentação na web com alguns endereços de URL típicos. Agora preciso adicionar um reescrito para uma linguagem diferente, exemplos:
domain/club -> do not change
domain/club/path -> do not change
domain/club/path?search=somethingelse -> do not change
domain/en/club -> domain/club?lang=en
domain/en/club/path -> domain/club/path?lang=en
domain/en/club/path?search=something -> domain/club/path?search=something&lang=endomain
Minha ideia era dividi-lo em grupos domínio / idioma / clube / caminho? Pesquisar = algo e depois escrever
RewriteRule \/(?<language>[a-zA-Z]{2})\/club\/?(?<path>.*)\?(?<search>.*) /club/$1?search=$2&lang=$3
mas isso não considerará strings sem ?. Também não sei resolver a diferença com dois casos ?lang=e &lang=. Não encontrei nada online.
Estou fazendo isso no framework PHP existente (não em qualquer um dos padrões) e, portanto, tenho que fazer dessa forma (entenda com esses urls específicos).
Respostas
Parece que você está tornando isso mais complexo do que realmente é. A menos que você precise ser específico sobre a correspondência de "clube", parece que você só precisa remover o primeiro segmento de caminho quando se parece com um código de idioma de duas letras e movê-lo para o langparâmetro de URL na string de consulta.
Para isso, você pode fazer o seguinte, próximo ao topo do seu .htaccessarquivo:
RewriteRule ^([a-z]{2})/(.+) $2?lang=$1 [QSA,L]
Uma solicitação de /en/clubserá reescrita para /club?lang=ene /en/club/path?search=somethingpara /club/path?lang=en&search=something(observe que o langparâmetro de URL é o primeiro).
Explicação:
- O
RewriteRulepadrão corresponde apenas ao caminho do URL, não à string de consulta. O caminho da URL que corresponde também não tem um prefixo de barra. ([a-z]{2})- corresponde ao código de idioma de 2 letras (minúsculas). (Embora em sua regex, você tenha permitido letras maiúsculas também?) Este é um subpadrão de captura, portanto, é naturalmente armazenado na (primeira) referência anterior$1.- O
(.+)corresponde a tudo no caminho de URL que segue o segmento de caminho do código de idioma (e barra). Observe que isso corresponde a algo , não a nada . Por isso não vai ser bem sucedido para um pedido para/en/apenas/en/<something>. (Se isso precisar ser bem-sucedido/en/apenas também, altere este subpadrão para(.*).) Isso também é capturado e armazenado na (segunda) referência anterior$2. por exemplo. Solicitar/en/club/pathe$2reterclub/path. - O
QSAsinalizador anexa qualquer string de consulta que possa estar presente na solicitação inicial e lida com a "fusão" com qualquer string de consulta na string de substituição . por exemplo.search=something. No entanto, uma pequena diferença com o seu exemplo é que olangparâmetro do URL será o primeiro , não o último - embora isso não deva ser um problema.
No entanto, se isso funciona ou não, ainda depende de como sua "estrutura PHP" roteia URLs. Por exemplo, se for como o WordPress e olhar para a $_SERVER['REQUEST_URI']superglobal do PHP, então ainda verá o caminho da URL antes da reescrita.
Você provavelmente tem outras reescritas depois disso?
RewriteRule \/(?<language>[a-zA-Z]{2})\/club\/?(?<path>.*)\?(?<search>.*) /club/$1?search=$2&lang=$3mas isso não considerará strings sem
?. Também não sei resolver a diferença com dois casos?lang=e&lang=. Não encontrei nada online.
Existem vários problemas aqui:
- O regex não está ancorado no início do caminho do URL, por isso corresponde
/<anything>/en/etc. - Conforme observado acima, o caminho de URL correspondente ao
RewriteRulepadrão não começa com uma barra. - "isso não considerará strings sem
?" - o URL correspondente aoRewriteRulepadrão é apenas o caminho do URL. Isso não inclui a string de consulta. Portanto, tentar corresponder à string de consulta aqui simplesmente falhará. (Se você precisar corresponder à string de consulta, precisará de umaRewriteConddiretiva adicional e corresponder àQUERY_STRINGvariável do servidor.) - Não é um erro, mas não há necessidade de barras invertidas de escape no regex, já que a barra não tem nenhum significado especial aqui ( espaços são delimitadores de regex / argumento em arquivos de configuração do Apache). Conforme observado, isso não é estritamente um erro, assim como você pode fazer o escape da maioria dos caracteres com barra invertida, mas complica o regex e torna mais difícil de ler.
- Você está usando grupos capturados por nome (com suporte no Apache 2.4.8+), mas está usando referências numéricas na string de substituição . Você não pode usar os dois. (É mais fácil ficar com referências numéricas da IMO.)
- As referências anteriores na string de substituição parecem estar na ordem errada.
$1é o código do idioma. por exemplo. deveria ser mais parecido (embora ainda não esteja correto)./club/$2?search=$3&lang=$1 - "como resolver a diferença com dois casos
?lang=e&lang=" - OQSAsinalizador (Query String Append) faz isso para você. Exceto que a string de consulta é anexada , não prefixada .