Htaccess 不允许访问带有参数的子目录
Htaccess doesn't let access to sub directories with parameters
我正在尝试为 seo urls 创建一个 htaccess,我创建了我的 htaccess 所有 urls 工作正常排除带参数的子文件夹,它们重定向到站点文件夹。
sitefolder
是我的根所有文件都在那里。
示例:Url 应如下所示:
http://localhost/sitefolder/subcat/39/web-hosting
http://localhost/sitefolder/profile/1/username
在 htaccess 中是这样的:
RewriteRule ^subcat/(.*)/([a-zA-Z0-9_-]+)$ subcat.php?q=&slug= [L,NC]
RewriteRule ^profile/(.*)/([a-zA-Z0-9_-]+)$ show_profile.php?q=&slug= [L,NC]
第一个参数是 id,第二个是 slug,但是两个 urls 都不会转到 url。
这是我所有的 htacces 代码:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteRule ^contact-us contact-us.php [L,NC]
RewriteRule ^login login.php [L,NC]
RewriteRule ^register register.php [L,NC]
RewriteRule ^search search.php [L,NC]
RewriteRule ^about-us about-us.php [L,NC]
RewriteRule ^(.*)/([a-zA-Z0-9_-]+)$ detail.php?q=&slug= [L,NC]
RewriteRule ^cats categories.php [L,NC]
RewriteRule ^subcat/(.*)/([a-zA-Z0-9_-]+)$ subcat.php?q=&slug= [L,NC]
RewriteRule ^profile/(.*)/([a-zA-Z0-9_-]+)$ show_profile.php?q=&slug= [L,NC]
这就是我在 subcat.php
中获取参数的方式,我不会在出错时重定向到索引,所以我认为这不是因为 php :
if(!empty($_GET['slug']) AND !empty($_GET['q'])) {
$slug = $_GET['slug'];
$pid = is_numeric($_GET['q']);
$userQuery = $handler->getPosts("SELECT * FROM categories WHERE catId = ?", [$pid])->fetchAll();
if($userQuery) {
foreach($userQuery as $user){
$catid = intval($user['catId']);
$cat_title = htmlspecialchars($user['catName']);
$cat_seo_url = htmlspecialchars($user['cat_seo_url']);
$cat_descriptions = htmlspecialchars($user['cat_desc']);
$cat_keywords = htmlspecialchars($user['cat_keys']);
$cat_created = htmlspecialchars($user['cat_created_at']);
$cat_img = htmlspecialchars($user['cat_img']);
}
}else{
echo "Something went wrong while execute query.";
exit();
}
}else{
echo "Something went wrong with parameters";
exit();
}
如果正在调用 subcat.php
(正如您在评论中所说),那么 .htaccess
不是问题。但是在您发布的任何代码中都没有重定向到 index.php
(或任何类型的重定向)。
但是,此行似乎存在运行时错误:
$pid = is_numeric($_GET['q']);
is_numeric()
只是测试参数是否为数字并且 return 是一个布尔值,它不是 return 该变量的数值,这似乎是您所期望的.因此,无论 q
.
的值如何,您的 SELECT 总是会失败(或 return 第一项)
您可能需要这样的东西来检索所述 URL 参数的实际值:
$pid = is_numeric($_GET['q']) ? (int)$_GET['q'] : 0;
但是您需要首先验证这些 URL 参数(即 $_GET
变量)是否已传递,否则,您的脚本将发出 E_NOTICE 消息.
更新:
与您的 RewriteRule
指令有冲突:
RewriteRule ^(.*)/([a-zA-Z0-9_-]+)$ detail.php?q=&slug= [L,NC]
RewriteRule ^cats categories.php [L,NC]
RewriteRule ^subcat/(.*)/([a-zA-Z0-9_-]+)$ subcat.php?q=&slug= [L,NC]
RewriteRule ^profile/(.*)/([a-zA-Z0-9_-]+)$ show_profile.php?q=&slug= [L,NC]
当您请求 http://localhost/sitefolder/subcat/38/web-design
时,它将被此处的第一条规则捕获,该规则将请求重写为 detail.php?q=subcat/39&slug=web-design
,而不是您期望的 subcat.php
。这大概 失败 ,因为 q=subcat/39
可能无效(我猜是触发重定向到 /sitefolder/
)?
您需要更改这些规则的顺序 and/or 使正则表达式更具体以避免冲突。例如。如果 q
应该是一个数字 id,那么只匹配一个数字值 (\d+
),而不是字面上的 anything (.*
),这就是您目前正在匹配。
RewriteRule ^contact-us contact-us.php [L,NC]
您还应该在您的正则表达式中包含 end-of-string 锚点,否则这些规则也将匹配重写的 URL 并导致不必要的循环。例如:
RewriteRule ^contact-us$ contact-us.php [L,NC]
我还质疑此处使用 NC
标志,因为它可能通过允许 contact-us
和 CONTACT-US
(以及两者之间的所有内容)访问来创建重复内容问题相同的资源。
总结
换句话说,您的规则应该更像这样:
RewriteRule ^contact-us$ contact-us.php [L]
RewriteRule ^login$ login.php [L]
RewriteRule ^register$ register.php [L]
RewriteRule ^search$ search.php [L]
RewriteRule ^about-us$ about-us.php [L]
RewriteRule ^cats$ categories.php [L]
RewriteRule ^(\d+)/([\w-]+)$ detail.php?q=&slug= [L]
RewriteRule ^subcat/(\d+)/([\w-]+)$ subcat.php?q=&slug= [L]
RewriteRule ^profile/(\d+)/([\w-]+)$ show_profile.php?q=&slug= [L]
(\w
是 shorthand 字符 class 用于 [a-zA-Z0-9_]
。)
通过使正则表达式更具体,您可以避免冲突。指令从上到下执行。第一个匹配的规则获胜。
我正在尝试为 seo urls 创建一个 htaccess,我创建了我的 htaccess 所有 urls 工作正常排除带参数的子文件夹,它们重定向到站点文件夹。
sitefolder
是我的根所有文件都在那里。
示例:Url 应如下所示:
http://localhost/sitefolder/subcat/39/web-hosting
http://localhost/sitefolder/profile/1/username
在 htaccess 中是这样的:
RewriteRule ^subcat/(.*)/([a-zA-Z0-9_-]+)$ subcat.php?q=&slug= [L,NC]
RewriteRule ^profile/(.*)/([a-zA-Z0-9_-]+)$ show_profile.php?q=&slug= [L,NC]
第一个参数是 id,第二个是 slug,但是两个 urls 都不会转到 url。
这是我所有的 htacces 代码:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteRule ^contact-us contact-us.php [L,NC]
RewriteRule ^login login.php [L,NC]
RewriteRule ^register register.php [L,NC]
RewriteRule ^search search.php [L,NC]
RewriteRule ^about-us about-us.php [L,NC]
RewriteRule ^(.*)/([a-zA-Z0-9_-]+)$ detail.php?q=&slug= [L,NC]
RewriteRule ^cats categories.php [L,NC]
RewriteRule ^subcat/(.*)/([a-zA-Z0-9_-]+)$ subcat.php?q=&slug= [L,NC]
RewriteRule ^profile/(.*)/([a-zA-Z0-9_-]+)$ show_profile.php?q=&slug= [L,NC]
这就是我在 subcat.php
中获取参数的方式,我不会在出错时重定向到索引,所以我认为这不是因为 php :
if(!empty($_GET['slug']) AND !empty($_GET['q'])) {
$slug = $_GET['slug'];
$pid = is_numeric($_GET['q']);
$userQuery = $handler->getPosts("SELECT * FROM categories WHERE catId = ?", [$pid])->fetchAll();
if($userQuery) {
foreach($userQuery as $user){
$catid = intval($user['catId']);
$cat_title = htmlspecialchars($user['catName']);
$cat_seo_url = htmlspecialchars($user['cat_seo_url']);
$cat_descriptions = htmlspecialchars($user['cat_desc']);
$cat_keywords = htmlspecialchars($user['cat_keys']);
$cat_created = htmlspecialchars($user['cat_created_at']);
$cat_img = htmlspecialchars($user['cat_img']);
}
}else{
echo "Something went wrong while execute query.";
exit();
}
}else{
echo "Something went wrong with parameters";
exit();
}
如果正在调用 subcat.php
(正如您在评论中所说),那么 .htaccess
不是问题。但是在您发布的任何代码中都没有重定向到 index.php
(或任何类型的重定向)。
但是,此行似乎存在运行时错误:
$pid = is_numeric($_GET['q']);
is_numeric()
只是测试参数是否为数字并且 return 是一个布尔值,它不是 return 该变量的数值,这似乎是您所期望的.因此,无论 q
.
您可能需要这样的东西来检索所述 URL 参数的实际值:
$pid = is_numeric($_GET['q']) ? (int)$_GET['q'] : 0;
但是您需要首先验证这些 URL 参数(即 $_GET
变量)是否已传递,否则,您的脚本将发出 E_NOTICE 消息.
更新:
与您的 RewriteRule
指令有冲突:
RewriteRule ^(.*)/([a-zA-Z0-9_-]+)$ detail.php?q=&slug= [L,NC] RewriteRule ^cats categories.php [L,NC] RewriteRule ^subcat/(.*)/([a-zA-Z0-9_-]+)$ subcat.php?q=&slug= [L,NC] RewriteRule ^profile/(.*)/([a-zA-Z0-9_-]+)$ show_profile.php?q=&slug= [L,NC]
当您请求 http://localhost/sitefolder/subcat/38/web-design
时,它将被此处的第一条规则捕获,该规则将请求重写为 detail.php?q=subcat/39&slug=web-design
,而不是您期望的 subcat.php
。这大概 失败 ,因为 q=subcat/39
可能无效(我猜是触发重定向到 /sitefolder/
)?
您需要更改这些规则的顺序 and/or 使正则表达式更具体以避免冲突。例如。如果 q
应该是一个数字 id,那么只匹配一个数字值 (\d+
),而不是字面上的 anything (.*
),这就是您目前正在匹配。
RewriteRule ^contact-us contact-us.php [L,NC]
您还应该在您的正则表达式中包含 end-of-string 锚点,否则这些规则也将匹配重写的 URL 并导致不必要的循环。例如:
RewriteRule ^contact-us$ contact-us.php [L,NC]
我还质疑此处使用 NC
标志,因为它可能通过允许 contact-us
和 CONTACT-US
(以及两者之间的所有内容)访问来创建重复内容问题相同的资源。
总结
换句话说,您的规则应该更像这样:
RewriteRule ^contact-us$ contact-us.php [L]
RewriteRule ^login$ login.php [L]
RewriteRule ^register$ register.php [L]
RewriteRule ^search$ search.php [L]
RewriteRule ^about-us$ about-us.php [L]
RewriteRule ^cats$ categories.php [L]
RewriteRule ^(\d+)/([\w-]+)$ detail.php?q=&slug= [L]
RewriteRule ^subcat/(\d+)/([\w-]+)$ subcat.php?q=&slug= [L]
RewriteRule ^profile/(\d+)/([\w-]+)$ show_profile.php?q=&slug= [L]
(\w
是 shorthand 字符 class 用于 [a-zA-Z0-9_]
。)
通过使正则表达式更具体,您可以避免冲突。指令从上到下执行。第一个匹配的规则获胜。