我的.htaccess文件遇到了问题.

该文件将难看的URL(如http://localhost/news.php?article_slug=example-1)更改为http://localhost/news/example-1

这可以完美地工作,但是当我使用http://localhost/news时,我得到一个404错误.

在news.php中,我有一个重定向;因此,如果URL中没有文章段,它将重定向到latest.php.

我在news.php上的PHP代码

$article_slug=$_GET['article_slug'];
if (empty($_GET)) {
header("Location: ../latest.php");
die();// no data passed by get
}

这是我当前在我的.htaccsess文件中拥有的内容

Options -MultiViews
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteRule ^news/([\w\d-]+)$ /news.php?article_slug=$1[QSA,L]
RewriteCond %{QUERY_STRING} article_slug=([\w\d-]+)
RewriteRule ^news$ /news/%1 [R,L]

RewriteRule ^category/([\w-]+)$ /category.php?category_slug=$1&page=$2 [QSA]

当我自己try 调试它时,(with very little knowledge)并添加以下代码行,它重定向到latest.php

RewriteRule ^([^/]*)/?$ /news.php [L,QSA]

但是在重定向的页面上,我得到了以下错误

The page isn’t redirecting properly

Firefox has detected that the server is redirecting the request for this 
address in a way that will never complete.

This problem can sometimes be caused by disabling or refusing to accept cookies

当我以IMSoP的身份使用Firefox中的开发人员工具时,我看到的只是多次重新加载了Latest.php.

这不仅隔离到latest.php,而且还隔离到服务器上未在Access文件中列出的任何文件

当我删除这行时

RewriteRule ^([^/]*)/?$ /news.php [L,QSA]

我可以加载PHP文件,但它不能从news.php重定向,并且找不到http://localhost/news,但http://localhost/news/example-1可以工作.

推荐答案

但是当我转到http://localhost/news时,我得到一个404错误.

您的规则都没有捕捉到这样的请求,因此不会发生重写,您会得到404.

RewriteRule ^([^/]*)/?$ /news.php [L,QSA]

这会将所有内容重写为/news.php,包括您在PHP脚本中重定向到的/latest.php,循环重复,导致重定向循环到/latest.php.

然而,在您的PHP代码中,这个重定向似乎也假定原始请求上有一个斜杠.也就是说.应该是/news/(带尾部斜杠),而不是您在问题中所说的/news(没有尾部斜杠).

最好在您的PHP脚本中重定向到根相对(或绝对URL).也就是说.header('Location: /latest.php');

RewriteRule ^news/([\w\d-]+)$ /news.php?article_slug=$1[QSA,L]
RewriteCond %{QUERY_STRING} article_slug=([\w\d-]+)
RewriteRule ^news$ /news/%1 [R,L]

(请注意,在第一个规则中,您在"标志"参数之前缺少一个space.)

第一个规则可以修改为允许news/个,而不仅仅是news/<something>个.这是通过简单地将捕获子模式上的量词从+(1或更多)更改为*(0或更多)来实现的.

第二条规则是目前什么都不做.你可能应该在这里瞄准news.php人.但规则的顺序也是错误的.

正如您前面问题的my answer中所指出的,\d速记字符类不是必需的,因为\w(单词字符)已经包括数字.

请try 以下操作:

RewriteCond %{QUERY_STRING} (?:^|&)article_slug=([\w-]*)(?:$|&)
RewriteRule ^news\.php$ /news/%1 [R=301,L]

RewriteRule ^news/([\w-]*)$ /news.php?article_slug=$1 [QSA,L]

注意,第一条规则应该是301(永久)重定向,而不是302(最初).但一定要先用302进行测试,以避免潜在的缓存问题.

这允许请求达到/news/,但不能达到/news(没有尾随斜杠).其中只有一种可能是规范的.如果您还需要处理/news,则应该重定向以附加尾随斜杠(因此/news/是规范的,并且您应该始终链接到该URL).例如,在上述两个规则之前:

# Append trailing slash if omitted (canonical redirect)
RewriteRule ^news$ /$0/ [R=301,L]

摘要

综合以上几点:

Options -MultiViews

RewriteEngine On

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

# Append trailing slash if omitted (canonical redirect)
RewriteRule ^news$ /$0/ [R=301,L]

RewriteCond %{QUERY_STRING} (?:^|&)article_slug=([\w-]*)(?:$|&)
RewriteRule ^news\.php$ /news/%1 [R=301,L]

RewriteRule ^news/([\w-]*)$ /news.php?article_slug=$1 [QSA,L]

RewriteRule ^category/([\w-]+)$ /category.php?category_slug=$1 [QSA,L]

然而,现在同样的情况也适用于您的/category URL.这一点也在你的earlier question人中讨论过.(我删除了多余的&page=$2部分,添加了缺少的L标志.)

如果您有许多这样的URL遵循类似的模式(例如,newscategory等),您不一定需要为每一个单独的规则.(这是给读者的练习.)


UPDATE:

$article_slug=$_GET['article_slug'];
if (empty($_GET)) {
header("Location: ../latest.php");
die();// no data passed by get
}

正如 comments 中所讨论的那样,这应该是:

$article_slug = $_GET['article_slug'] ?? null;
if (empty($article_slug)) {
    header("Location: /latest.php");
    die(); // no data passed by get
}

Php相关问答推荐

如何使用查询范围在Statamic中按组过滤用户?

Laravel中的通配符Undot数组

为什么注册SIGHUP的处理程序函数会阻止在PHP CLI中等待输入时点击X关闭Xterm窗口?""

如何使用属性#[Embedded]嵌入带有规则的对象集合?

以编程方式更改新订单、已取消订单和失败订单的邮箱WooCommerce通知

ForHumans函数中的月当量与单位限制

添加登录:需要app.yaml仍然允许所有拥有Google帐户的人访问

在Laravel中为表添加前缀,以将它们逻辑地分组

从AJAX响应中获取一个未定义的html

在WooCommerce上设置简单和可变产品的最小订单量

PHP按另一个二维数组的排序顺序对二维数组进行排序

WooCommerce产品页面上没有产品详细信息

将可编辑的计费自定义字段添加到 WooCommerce 管理单个订单

在 WordPress 中将自定义帖子类型永久链接设置为 root

通过ajax发送数据到下拉列表未完全设置为所选

在 WooCommerce 我的帐户自定义部分显示未购买的产品

php var_dump(1) 返回字符串(4)

每个发布请求 Laravel 9 的 CSRF 令牌不匹配

使用 Eloquent 更新现有的外键值

使用 OOP PHP 创建动态 WHERE 子句.如何实现 BETWEEN 运算符?