如何使用 .htaccess 创建友好的 URL?
Posted
技术标签:
【中文标题】如何使用 .htaccess 创建友好的 URL?【英文标题】:How can I create friendly URLs with .htaccess? 【发布时间】:2011-03-03 06:46:24 【问题描述】:我很难使用 .htaccess。我想为我正在开发的网站创建友好的 URL...
基本上我想转换这个:
http://website.com/index.php?ctrl=pelicula&id=0221889
http://website.com/index.php?ctrl=pelicula&id=0160399&tab=posters
进入这个:
http://website.com/pelicula/0221889/
http://website.com/pelicula/0221889/posters/
如果我以后需要它,我也想知道如何像这样将文章标题添加到 URL 的末尾(我使用的是 PHP):
http://website.com/pelicula/0221889/the-article-name/
http://website.com/pelicula/0221889/the-article-name/posters/
注意:***的方法对我也有好处,比如这个问题的url是:
http://***.com/questions/3033407/htacces-to-create-friendly-urls-help-needed
但是你可以在 id 后面放任何东西,它也可以工作。像这样:
http://***.com/questions/3033407/just-anything-i-want
我使用了一些自动网络工具来创建 .htacces 文件,但它无法正常工作。所以我请求你的帮助。
如果您能推荐 .htacces 最佳实践和建议,我也会很高兴..
编辑:根据我得到的一些答案,我把这个:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %REQUEST_FILENAME !-f
RewriteRule ^/([^/]+)/([^/]+)/?([^/]*)/?$ index.php?ctrl=$1&id=$2&tab=$3 [QSA,L]
</IfModule>
但我收到默认主机“找不到页面”错误。
我也试过了:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %REQUEST_FILENAME !-f
RewriteRule ^([^/]+)/(\d+)/([^/]+)/?$ index.php?ctrl=$1&id=$2&tab=$3 [QSA,L]
RewriteRule ^([^/]+)/(\d+)/?$ index.php?ctrl=$1&id=$2 [QSA,L]
RewriteRule ^([^/]+)/?$ index.php?ctrl=$1 [QSA,L]
</IfModule>
这也行不通。它会将我带到我的默认 404.php 页面。
mod_rewrite 已启用并正在工作。
救命!
【问题讨论】:
***.com/questions/2569725/… ***.com/questions/2088804/… ***.com/questions/2549408/… ... 要查看您的 URL 被重写为什么,请尝试在 index.php 的顶部回显 $_GET 或使用重写日志进行调试。 httpd.apache.org/docs/2.0/mod/mod_rewrite.html#rewritelog 你“真的”确定重写工作正常吗?我曾经在配置错误的 apache 配置文件时遇到过同样的问题。 webune.com/forums/…真的帮了我 【参考方案1】:重写规则 ^stuff/([^/.]+)/([^/.]+)/([^/.]+)/?$ index.php?ctrl=$1&id=$2&tab=$3 [ L,NC,QSA] RewriteRule ^stuff/([^/.]+)/([^/.]+)/?$ index.php?ctrl=$1&id=$2 [L,NC,QSA]
【讨论】:
【参考方案2】:根据经验,我建议调整您的 URI 方案,以便更轻松地仅将规则应用于您知道已重写的 URI。例如
转换这个:
http://website.com/index.php?ctrl=pelicula&id=0221889
http://website.com/index.php?ctrl=pelicula&id=0160399&tab=posters
在其中(我已经使用了“东西”这个词,但这确实应该是描述您可能会找到的东西,即“商店”或“图书馆”或其他任何内容):
http://website.com/stuff/pelicula/0221889/
http://website.com/stuff/pelicula/0221889/posters/
为此,您可以在网站的***文件夹中放置一个 .htaccess 文件,其中包含以下规则:
RewriteEngine on
RewriteRule ^stuff/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ index.php?ctrl=$1&id=$2&tab=$3 [L,NC,QSA]
RewriteRule ^stuff/([^/\.]+)/([^/\.]+)/?$ index.php?ctrl=$1&id=$2 [L,NC,QSA]
通过地址的“东西”部分(重命名为适当的名称),您不会意外地重写其他资产,例如图像、CSS 包含和 javascript 包含。
作为旁注,您提到:
这也行不通。它会将我带到我的默认 404.php 页面。
您的 404 错误重定向声明在哪里?
【讨论】:
【参考方案3】:我在我的.htaccess
文件中使用它
RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
RewriteRule .* rewrite.php [L]
基本上,如果它不作为文件或目录存在,请使用 rewrite.php 并让它负责 URL 解析等。我相信这是您可以重写的最基本方法。
另外,查看var_dump($_SERVER)
的结果(你知道的地方),看看你认为最顶层的目录是否真的是最顶层的目录,例如:你可能正在写/var/www/domain/www/index.php
而不是/var/www/domain/index.php
【讨论】:
【参考方案4】:确保目录树上没有任何其他 .htaccess 文件与您网站的 .htaccess 冲突。
【讨论】:
【参考方案5】:刚刚在本地进行了测试,它似乎可以满足您的需求:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %REQUEST_FILENAME !-f
RewriteRule ^([^/.]+)(?:/)?$ /index.php?ctrl=$1 [L]
RewriteRule ^([^/.]+)/([^/.]+)(?:/)?$ /index.php?ctrl=$1&id=$2 [L]
RewriteRule ^([^/.]+)/([^/.]+)/([^/.]+)(?:/.*)?$ /index.php?ctrl=$1&id=$2&tab=$3 [L]
</IfModule>
这就是它的作用:
对于像 http://website.com/pelicula/ 这样的路径,重定向到 /index.php?ctrl=pelicula 对于像 http://website.com/pelicula/0221889 这样的路径,重定向到 /index.php?ctrl=pelicula&id=0221889 对于像 http://website.com/pelicula/0221889/posters/ 这样的路径,重定向到 /index.php?ctrl=pelicula&tab=posters 对于像 http://website.com/pelicula/0221889/posters/anything-can-go-here 这样的路径,重定向到 /index.php?ctrl=pelicula&tab=posters 并忽略路径的其余部分。这些重写将在有或没有尾部斜杠的情况下工作 - 如果您希望它们仅在没有斜杠的情况下工作,请从前两个重写的末尾删除 (?:/)?
。您还可以根据需要使用 mod_rewrite 添加或删除尾部斜杠。
【讨论】:
它在我的虚拟主机上不起作用。我收到此错误:内部服务器错误。服务器遇到内部错误或配置错误,无法完成您的请求。有什么想法吗? 尝试在所有重写规则中删除 index.php 前面的斜线。 我删除了斜线,同样的错误。我认为这可能是语法错误,因为当我尝试“jfoucher”提供的代码时,我没有遇到这个问题...... 您有权访问服务器日志吗?你能看到重写日志中发生了什么吗? 我无法访问服务器日志,请阅读我的其他问题***.com/questions/3076122/…【参考方案6】:拥有这个网址:
http://website.com/pelicula/0221889/posters
改写成这样:
http://website.com/index.php?ctrl=pelicula&id=0221889&tab=posters
我会这样做:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %REQUEST_FILENAME !-f
RewriteRule ^/([^/]+)/([^/]+)/?([^/]*)/?$ index.php?ctrl=$1&id=$2&tab=$3 [QSA,L]
</IfModule>
您必须选择是否要将标题放在 id 之后并一直这样做,因为 tab 变量位于最后一个位置:您必须知道它是数字 3 还是数字 4。 如果你这样做:
RewriteRule ^/([^/]+)/([^/]+)/?([^/]*)/?([^/]*)$ index.php?ctrl=$1&id=$2&tab=$4 [QSA,L]
第三个括号没有被捕获,因此可以包含任何内容。
希望有帮助
【讨论】:
我把它放在 .htacces 文件中,但它不起作用,知道为什么吗? 那么,你得到了什么 eeor 之王?你启用了 mod_rewrite 吗?【参考方案7】:在http://website.com/
的文档根目录中,我会像这样放置一个htaccess
文件:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %REQUEST_FILENAME !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
然后在您的 PHP 脚本中,您可以随意操作 $_GET['url']
变量:
$path_components = explode('/', $_GET['url']);
$ctrl=$path_components[0];
$id=$path_components[1];
$tab=$path_components[2];
【讨论】:
我需要更改所有 Web 应用程序才能使用它吗?我的意思是,我需要更改每个页面中的所有 $_GET 吗? @Jonathan:不,这就是重点!您只会在 index.php 页面中拥有该代码。然后 index.php 可以根据 $_GET 变量决定做什么和include
所需的页面
这被称为前端控制器模式,恕我直言。【参考方案8】:
第一个假设您的 .htaccess 文件位于根目录中:
RewriteRule ^([a-zA-Z]+)/([0-9]+)(/)?$ index.php?ctrl=$1&id=$2
第二个:
RewriteRule ^([a-zA-Z]+)/([0-9]+)/([a-zA-Z]+)(/)?$ index.php?ctrl=$1&id=$2&tab=$3
或者如果它总是posters
而不是不同的标签:
RewriteRule ^([a-zA-Z]+)/([0-9]+)/posters(/)?$ index.php?ctrl=$1&id=$2&tab=posters
我添加了 (/)?
,这应该意味着 URI 可以使用或不使用尾部斜杠。
至于另一个,我可能总是将文章保留在最后,以便重写或添加另一个 /value
,以便重写知道选项卡和文章之间的区别或从正则表达式中排除破折号。
【讨论】:
太棒了,这是我需要在 htacces 文件中放入的唯一行吗?以上是关于如何使用 .htaccess 创建友好的 URL?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 .htaccess 和 php 制作用户友好的 url
如何设置 htaccess 以从用户友好的 URL 获取参数以与 JS 一起使用