繁体   English   中英

用htacces仅重定向真实字符串(字母)

[英]Redirect only real strings (letters) with htacces

我要做的是让用户在命令行中输入搜索字符串,然后将其重定向到相应的页面。 例如:用户键入:www.mydomain.com/something,我将他定向到www.mydomain.com/page.php?id=27408

我在.htaccess中有一个命令:ErrorDocument 404 /index_404.php,因此该请求被发送到我的php脚本中,在我的数据库中搜索正确的ID,并将其引导至请求的页面。 –这很好。

不幸的是,由于每个404错误(例如,未找到某些图片)都被发送到该php页面,因此流量非常大,这使我感到困扰。 我有一个使用重定向301的解决方案-但是提供程序的服务器不允许我通过php-script生成.htaccess。

所以我的问题是:有没有一种方法可以检查请求是否仅匹配字母并仅重定向这些请求。 就像是:

错误文档404([a..z]中的请求)/index_404.php

并让其余默认处理? 如果是这样,请发送一个体面的例子。

这里是我的php-script的基本代码:

if (isset($_SERVER["REQUEST_URI"])) {
    $in = $_SERVER["REQUEST_URI"];
    $in = str_replace("/","",$in); //  
    dbconnect();
    $sql = 'select * from menu where REPLACE(menu," ","") = "'. $in;    
    $result = @mysql_query($sql);
    if ($data = @mysql_fetch_array($result)) {
        $out = 'page.php?id='.$data['id'];                                  
    }
}

if (isset($out)) {
    header("Location: ".$out);
} else {
    header("Location: "."index.php");
}

正如您所发现的,当您需要每个mimetype都没有异常发送到那里时,可以使用ErrorDocument ,但是事实并非如此。

让我们重新构造一下PHP代码,以便您可以打破对ErrorDocument的依赖,并在.htaccess中更适当地使用mod_rewrite 而不是从REQUEST_URI中读取,一种更常规的方法是构建PHP脚本以期望$_GET的参数。

改写:

首先,设置重写。 您只想匹配字母并将其发送到PHP脚本。 (它仍然使用index_404.php但是您可能要重命名它,因为它不再处理404了)。 /abcdabcd/efg类的请求将传递到PHP脚本。 诸如/main.css类的真实现有文件将不会发送到PHP; 该文件将被正确提供。 对于不存在的文件(例如/bad-image.png将与RewriteRule不匹配,因此将被视为常规404。

RewriteEngine On
# If the request isn't for an actual existing file
# (so images, CSS aren't interrupted)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# Send letters-only (and slashes) URI's to PHP into the query string param in=
# /? also allows a trailing slash optionally
RewriteRule ^([A-Za-z\/]+)/?$ index_404.php?in=$1 [L]

注意:我使用[A-Za-z\\/]+允许大写和小写,以及/因为您有在PHP中删除/的代码。 这样可以将/abc/abc/def类的URI发送到PHP。 如果只允许/abc不是 /abc/def ,请改用[A-Za-z]+ 如果您不想使用大写字母,只需删除AZ

现在,PHP处理程序...

上面使用查询字符串发送到PHP。 修改您的PHP以改为读取$_GET['in']

if (isset($_GET['in'])) {
  dbconnect();

  // Looks like you permit slashes as input but remove them here...
  $in = str_replace("/","",$_GET['in']);

  // You must escape this even though the Apache 
  // rewrite only permits a-z/
  $in = mysql_real_escape_string($in);

  // Get rid of those @ error suppressors
  $sql = "select * from menu where REPLACE(menu,' ','') = '$in'";

  // Do your query
  $result = mysql_query($sql);
  if ($data = mysql_fetch_array($result)) {
      $out = 'page.php?id='.$data['id'];                                  
  }
}
if (isset($out)) {
    header("Location: " . $out);
} else {
    header("Location: index.php");
}

请注意,PHP 5.5不建议使用mysql_*()扩展名。 最终将其从语言中删除,并且不应使用它编写新代码。 相反,现在是时候开始学习使用PDOMySQLi了 两者都通过prepare()/execute()支持准备好的语句, 这是保护代码免于SQL注入的推荐方法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM