一个原始php博客的漂亮链接.htaccess代码[复制]

bzzcjhmw  于 2022-11-16  发布在  PHP
关注(0)|答案(1)|浏览(99)

此问题在此处已有答案

Reference: mod_rewrite, URL rewriting and "pretty links" explained(5个答案)
上个月关门了。
我需要一个帮助的博客,这是在核心php,并希望创建一个漂亮的网址使用。
主index.php是一个blog页面,也是一个post页面,显示基于IF语句的单个blog post
因此,我想要实现是访问加载为https://example.com/my-blogpost-url-slughttps://example.com/?slug=my-blogpost-url-slug
www.example.com上已经有一个IF语句example.com/index.php,它检查是否有可用的post slug,如果没有,则重定向到404
已经访问example.com加载example.com/index.php
下面是我已经拥有的htaccess i代码

## force https
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]

## remove .php n co
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]

## remove www 
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.example.com
RewriteRule (.*) https://example.com/$1 [R=301,L]

## error documents
ErrorDocument 404 https://example.com/err?code=404
ErrorDocument 500 https://example.com/err?code=500
dldeef67

dldeef671#

因此,我想要实现是访问https://example.com/?slug=my-blogpost-url-slug,加载为https://example.com/my-blogpost-url-slug
实际上是反过来的...用户访问https://example.com/my-blogpost-url-slug(应该是链接的目标),它就像请求https://example.com/index.php?slug=my-blogpost-url-slug一样加载--这是要重写的URL。注意,我在重写中包含了index.php,否则您将依赖于mod_dir为DirectoryIndex文档发出额外的子请求。
这称为前端控制器 * 模式 *。index.php是“前端控制器”。

## remove .php n co
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]

但是首先,您需要“纠正”您的规则(如上所述),即## remove .php n co在重写请求之前首先检查相应的.php文件是否存在,否则这将与前端控制器模式相冲突,我们需要在下一节中编写该模式来重写您的“漂亮”URL。
上述规则的“问题”在于它重写了不存在的任何内容,而这基本上是前端控制器需要做的。
上面应该这样写:

RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]

当在正则表达式字符类中使用时,你不需要反斜杠转义文字点,因为它们在这个上下文中没有特殊的含义。NC标志是多余的,因为正则表达式^([^.]+)$已经匹配了大小写字母。

前端控制器模式

这才是你真正要问的...
我们可以通过限制规则匹配的正则表达式来避免额外的文件系统检查。例如,只允许/my-blogpost-url-slug形式的URL,其中 slug 不能包含斜杠或点(这将与实际文件冲突)。
您可以在文件末尾添加一条规则来实现此目的:

# Rewrite "/<slug>" to "/index.php?slug=<slug>"
RewriteRule ^[^/.]+$ index.php?slug=$0 [L]

$0反向引用包含与RewriteRule * 模式 * 匹配的完整URL路径。请注意,此URL路径上没有斜杠前缀。如果您希望在请求的URL上有其他查询字符串,请包括QSA标志。
当调用文档根目录(即主页)时,将调用index.php(如您所述),但slug URL参数将被忽略。
请注意,您不需要像之前那样在文件中多次重复RewriteEngine指令。为了便于阅读,应该在文件的顶部执行一次。

摘要

您的规则顺序也不正确。规范重定向应该在前面。例如,您的规则应该如下所示(注意下面关于ErrorDocument指令的其他要点):

## error documents
ErrorDocument 404 /err.php
ErrorDocument 500 /err.php

RewriteEngine On

## force https
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]

## remove www 
RewriteCond %{HTTP_HOST} ^www\.example\.com
RewriteRule (.*) https://example.com/$1 [R=301,L]

## remove .php n co
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]

#### FRONT-CONTROLLER ####
# Rewrite "/<slug>" to "/index.php?slug=<slug>"
RewriteRule ^[^/.]+$ index.php?slug=$0 [L]
  • 旁白 *
ErrorDocument 404 https://example.com/err?code=404
ErrorDocument 500 https://example.com/err?code=500

您应该在ErrorDocument指令中使用相对于根目录的URL路径,而不是绝对URL,正如您在这里所写的那样。这将触发302(临时)重定向到错误文档,并且HTTP响应状态将丢失。
您还应该使用完整的文件名,我假设它是err.php,而不依赖于其他规则。
这样就不需要在code URL参数中传递HTTP状态代码,因为这可以在PHP代码的$_SERVER['REDIRECT_STATUS']超级全局中访问。
因此,这应该写成如下形式:

ErrorDocument 404 /err.php
ErrorDocument 500 /err.php

注意:在.htaccess中定义了ErrorDocumentlate,您不太可能捕获真实的的500(内部服务器)错误。
这些指令在.htaccess文件中的顺序实际上并不重要,但是,首先在文件的顶部而不是在文件的末尾定义这些指令更符合逻辑。

相关问题