0

我终于想出了一个好/简单的方法来在我的网站上以下面这种格式使用正则表达式制作干净的 URL,但是它需要一个非常大的 .htaccess 文件,我从这里的帖子中知道它应该不会很糟糕关于使用 mod_rewrite 的性能,但我从未真正看到它以我现在的方式使用,我网站的几乎每个页面都有单独的条目。

下面是一个条目的例子,1页有2个条目,第一个条目重写

http://www.example.com/users/online/friends/

http://www.example.com/index.php?p=users.online.friends

它工作得很好,但是如果用户不在第一页上,那么在 URL 中添加了另一件事进行分页,当这种情况发生时我不得不写另一个条目来重写,这是正确的方法还是应该以某种方式组合?

RewriteRule ^users/online/friends/*$ ./index.php?p=users.online.friends&s=8
RewriteRule ^users/online/friends/(\d+)/*$ ./index.php?p=users.online.friends&s=8&page=$1

第二个会这样做

http://www.example.com/users/online/friends/22/

http://www.example.com/index.php?p=users.online.friends&page=22

4

3 回答 3

3

是的,没关系。我想它们可以组合成一个规则,但实际上没有任何必要。

您可以考虑将页面作为 URL 的一部分,而不是:

http://www.domain.com/users/online/friends/22/

只需:

http://www.domain.com/users/online/friends?page=22

然后有一个规则,例如:

RewriteRule ^users/online/friends/?$ ./index.php?p=users.online.friends&s=8 [L,QSA]

追加查询字符串

编辑:有几种方法可以减少您拥有的重写规则的数量。

首先,在搜索词中使用通配符,例如:

RewriteRule ^users/(\w+)/(\w+)$ /index.php?p=users.$1.$2 [L,QSA]

会减少相当多的规则。

其次,如果您通过 /index.php 传递所有内容,只需考虑在那里委派所有请求:

RewriteRule ^(users/*)$ /index.php/$1 [L,QSA]

该规则使用第三种技术:不是通过查询字符串参数传递路径信息,而是通过额外的路径信息传递它。可以通过$_SERVER['PATH_INFO'].

话虽这么说,很多规则并不一定是坏的。至少它对你的所有行为都是明确的。但是,您必须注意的是制造维护噩梦。

于 2009-09-21T02:25:03.857 回答
3

这取决于您认为更具可读性的内容,但以下是您可以使用单个规则执行此操作的方法:

RewriteRule ^users/online/friends(/(\d+))?/*$ ./index.php?p=users.online.friends&s=8&page=$2

编辑更忠实于原始问题中斜杠的处理。是:RewriteRule ^users/online/friends/((\d+)/*)?$ ./index.php?p=users.online.friends&s=8&page =$2 )

在这里,我刚刚输入了“(...)?” 围绕 url 的最后部分使其成为可选匹配,并将反向引用更改为 $2。

当然,这实际上将http://www.domain.com/users/online/friends/重写为:

http://www.domain.com/index.php?p=users.online.friends&page=

因此,您的 PHP 代码必须检查页面参数是否为非空。

于 2009-09-21T02:44:59.777 回答
2
# Initial step
RewriteCond %{QUERY_STRING} !(?:^|&)p=
RewriteRule ^([^/]+)/(.+) /$2?p=$1 [QSA]

# Subsequent steps
RewriteCond %{QUERY_STRING} ((?:[^&]*&)*?)p=([^&]*)(.*)
RewriteRule ^([^/]+)/(.+) /$2?%1p=%2.$1%3

# Last step with page number
RewriteRule ^(\d+)/?$ /index.php?page=$1 [QSA,L]

# Last step without page number
RewriteCond %{QUERY_STRING} (?:((?:[^&]*&)*?)p=([^&]*))?(.*)
RewriteRule ^([^/]+)/?$ /index.php?%1p=%2.$1%3 [L]

这将分几个步骤重写 URL:

  1. http://www.domain.com/users/online/friends/22/
  2. http://www.domain.com/online/friends/22/?p=users
  3. http://www.domain.com/friends/22/?p=users.online
  4. http://www.domain.com/22/?p=users.online.friends
  5. http://www.domain.com/index.php?p=users.online.friends&page=22

以下是一种更简单的方法,但需要您更改脚本:

RewriteRule ^(.*?)(?:/(\d+))?/?$ /index.php?p=$1&page=$2 [QSA,L]

它将一步完成所有事情,但有一点不同:

  1. http://www.domain.com/users/online/friends/22/
  2. http://www.domain.com/index.php?p=users/online/friends&page=22

添加s=8查询参数需要更多的工作:

  1. 为每页创建一个带有菜单编号的文本文件。
  2. 添加RewriteMap指令。
  3. 更改倒数第二个规则以使用与RewriteCond最后一个规则相同的规则。
  4. 添加&s=%{menumap:%2|0}到最后两个规则。
于 2009-09-21T03:08:53.700 回答