0

在周末的大部分时间里,我一直在努力解决 .htaccess 问题,但我一直在跌跌撞撞;我可以让服务器使用一组规则,但一次不能超过一个。

我的应用程序由几个页面组成:

  • 主页从详细信息页面中提取内容(以及详细信息页面不包含的内容),并带有可选的查询字符串参数;例如?s=item-name
  • 详细信息页面使用可选的查询字符串参数(与主页相同的参数;例如?s=item-name- 这将引用完全相同的内容)引入内容
  • 收藏页面
  • A 相关页面

这些页面中的每一个都是文档根目录中的一个 php 文件(index.php、detail.php、collection.php、相关 php)。

我想达到的目标:

  • 用户应该能够转到mydomain.com/detail/mydomain.com/detail(因此允许尾部斜杠)而不是mydomain.com/details.php
  • 如果存在,则查询字符串参数 ( ?s=item-name) 应在页面的尾部斜杠之后输入(因此mydomain.com/item-name而不是mydomain.com/?s=item-name;mydomain.com/detail/item-name而不是mydomain.com/detail.php?s=item-name。所有页面都是这种情况,因此一次在一页上设置规则似乎相当麻烦......

这是我的 .htaccess 文件目前的样子,经过多次摆弄:

<IfModule mod_rewrite.c>  
    RewriteEngine on
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?s=$1 [L]
</IfModule>

这允许主页引入正确的内容,我相信它不会太远,允许任何页面做同样的事情,但我不能完全理解它。

任何人都可以帮忙吗?

4

1 回答 1

1
RewriteEngine On
RewriteBase /

# Specifics
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/([^/]+)/(.+)/?$
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^ %1.php?s=%2 [L]

# EDIT 1: This will also check for root pages. See notes below
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ([^/]+)/ $1 [R=301,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule (.+) $1.php [L,QSA]

# Everything else
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?s=$1 [L]

解释:

  1. 首先,我们检查完整的REQUEST_FILENAME不存在。
  2. 然后,我们检查格式如下:(/<something-without-slash>/<everything else>带有可选的斜杠)。
  3. 然后我们检查我们的第一个条件捕获是否作为 PHP 文件存在于文档根目录中。例如,如果我们请求foo/bar,它将检查是否/foo.php存在。
  4. 然后我们只需使用正确的查询字符串将请求路由到正确的文件。

因此,在您的情况下,当您请求时detail/item-name,服务器实际上会考虑detail.php?s=item-name为您提供响应。

注意:如果它不存在,请求将简单地将请求发送到index.php.

编辑:添加了对根页面的检测。但是请注意,我无法让它为这种检测留下斜线,因为它会自动修改.php为空s查询参数。不知道为什么......这就是为什么当它到达这个阶段时,它会删除任何尾随斜杠。这也有利于 SEO 评级/排名,因为它被视为一页,而不是两个重复。

于 2013-05-06T15:23:31.857 回答