多个和长查询的友好URL

我尝试了几个不同的问题:

上面的问题没有用,所以我开始开发一个替代方案,但我的代码返回404错误,多个请求( code1 ),并且一个请求运行良好( code2 )所以:

code1 ) - 不要工作 - 多次请求( code2 ) - 工作正常 - 单一请求

Code1

Options +FollowSymLinks -MultiViews
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /~loja/index.php?a=$1&genero=$2&material=$3&cor=$4&tamanho=$5&Ordenacao=$6 [NC,L,QSA]
    RewriteCond %{THE_REQUEST} ^.*/index\.php 
    RewriteRule ^(.*)index.php$ /~loja/$1/$2/$3/$4/$5/$6 [R=301,L]  
    DirectoryIndex index.php

现在看看正确的代码:

Code2

Options +FollowSymLinks -MultiViews
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([a-zA-Z0-9_-]+)$ /~loja/index.php?a=$1 [NC,L,QSA]
    RewriteCond %{THE_REQUEST} ^.*/index\.php 
    RewriteRule ^(.*)index.php$ /~loja/$1 [R=301,L]  
    DirectoryIndex index.php

code1 )有什么问题?

回答(1)

2 years ago

第一个规则集不起作用,因为目标网址包含7个细分,但 RewriteRule 匹配6个细分 . 如果在 RewriteRule 中的 $ 之前添加另一个 /([^/]*) ,它将起作用 .

所以,它是:

RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /~loja/index.php?a=$1&genero=$2&material=$3&cor=$4&tamanho=$5&Ordenacao=$6 [NC,L,QSA]

您可以通过在其末尾添加 ? 字符来使分段/字符可选 .

第一个规则集的第二部分完全错误,没有用处 . 首先,您应该注意 THE_REQUEST 变量包含完整的HTTP请求行作为documentation states

THE_REQUEST包含浏览器发送到服务器的完整HTTP请求行(例如,GET /index.html HTTP / 1.1) . 这不包括浏览器发送的任何其他标头 . 与以下大多数其他变量不同,此值尚未转义(解码) .

您不想使用它,请改用 REQUEST_URI .

404

您收到404错误的原因是因为 RewriteRule 无法匹配请求URI,因此URL不会被重写为index.php . 该目录层次结构在文件系统上不存在,因此404 .

可选的URI段

您的原始规则集期望精确计算URI参数 . 如果您需要更加灵活,可以尝试使用此规则集,该规则集接受1-7个段并将它们映射到查询字符串:

<IfModule mod_rewrite.c>
    RewriteEngine on

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    RewriteCond %{REQUEST_URI} !index\.php
    RewriteRule ^([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)$ /~loja/index.php?a=$1&genero=$2&material=$3&cor=$4&tamanho=$5&Ordenacao=$6 [NC,L,QSA]
</IfModule>

测试时,请注意空查询字符串 . 在PHP方面,您需要使用 empty() 而不是 isset() 来查看查询字符串是否存在 . 因为它们总是被设定,但是空的 .

不包括管理员/

为了排除要在 admin/ 路径上应用的规则,您可以像这样更新上面的 RewriteCond

RewriteCond %{REQUEST_URI} !(index\.php|admin)