在使用重写引擎时正确编码url


Encoding an url correctly while using a rewrite engine

我正在使用从Akelos框架中提取的mod_rewrite和路由系统。

我在搜索关键参数中使用一些符号时遇到了一个非常大的问题。

路由图如下:

$map->connect(":lang/search/:string", array('controller' => 'search','action' => 'index'));

在控制器中,我现在得到$this->registry->map['params']['get']['string']作为搜索关键字。

我找不到正确编码url的方法。例如,我们取字符串t' /#%&=

urlencode()给出t%5C+%2F%23%25%26%3D,页面显示The requested URL /site/en/search/t'+/#%&= was not found on this server.

rawurlencode()给出t%5C%20%2F%23%25%26%3D和页面显示相同。

你可以在这里下载或查看路由器类的源代码

我真的不想使用base64的url和这样的编码,你不能读取任何东西。

如果你需要,这里有一个.htaccess文件的内容,以及:

<IfModule mod_rewrite.c>
   RewriteEngine On
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>

这里是实际的工作文件进行测试。

如果您有时间,请下载这些文件并在您的服务器上测试。

指南:

controllerclass.php -简单的控制器框架,使searchcontroller.php通过定义一个类" controller "来工作

routerclass.php -从Akelos框架中提取的路由器类,可能存在错误

routes.php -一个你定义路由的地方,在我们的例子中我们只有/search/:string

searchcontroller.php -一个测试字符串的基本应用程序-/search/stringhere指向这个文件

index.php -所有初始化和路由发生的地方

.htaccess -我不认为这里有错误

我认为你不需要修改index.php, controllerclass.php, routes.php, searchcontroller.php

一个错误可能是在routerclass.php或可能有一些修复需要在.htaccess,我不相信。

看起来这个问题是关于RFC 3986第7.3节(后端转码)关于urlencodeurldecode。我稍微修改了http://php.net/manual/en/function.urlencode.php#97969:

的函数
function myUrlEncode($string) {
    $entities = array('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D', '%2B', '%24', '%2C', '%2F', '%5C', '%3F', '%25', '%23', '%5B', '%5D');
    $replacements = array('!', '*', "'", "(", ")", ";", ":", "@", "&", "=", "+", "$", ",", "/", "''", "?", "%", "#", "[", "]");
    return htmlspecialchars(str_replace($entities, $replacements, urlencode($string)));
}

注意%5C =>'htmlspecialchars() (htmlspecialchars)是关于安全性的,而不是能够使用特殊字符。输入可以是<script>...<h1>...等:))。

所以你会像这样使用它:

print("<b><i>URL Encode Tests</i></b><br /><br />
    <b>Works:</b> ".myUrlEncode($string[0])." <a href='"".HTTP_ROOT."/search/".myUrlEncode($string[0])."'">/search/".myUrlEncode($string[0])."</a><br />
    <b>Does not work:</b> ".myUrlEncode($string[1])." <a href='"".HTTP_ROOT."/search/".myUrlEncode($string[1])."'">/search/".myUrlEncode($string[1])."</a><br />
    <b>Does not work:</b> ".myUrlEncode($string[2])." <a href='"".HTTP_ROOT."/search/".myUrlEncode($string[2])."'">/search/".myUrlEncode($string[2])."</a><br />
");

这样做之后,搜索字符串#3 (' /#%&=)给出了一个PHP错误,如&;Method SearchController::t在…'index.php第30行"无效。我猜这是关于路由器中的正则表达式,所以你可能需要在那里做一些调整。

给出的错误是:

"请求的URL/网站/en/搜索/"

你有额外的词"网站"在它没有提到在你的问题,这使得很难解释,但错误似乎是来自Apache 而不是 PHP。

错误提示url没有被你的htaccess规则匹配。所以你不需要查看任何PHP代码来找出错误,错误就在Apache的某个地方。

进一步搜索-这是因为URL无效。%2f允许出现在查询字符串中,但不允许出现在路径中。因为它是无效的,所以在它到达重写规则之前服务器会拒绝它。

www.jampmark.com的链接给出了5种解决方案的优点和每个解决方案的问题,但是复制那么多材料到这里是不合适的。

  1. 在Apache中打开"AllowEncodedSlashes"指令
  2. url编码后将%2F替换为%252F,将%5C替换为%255C
  3. 双urlencode ()
  4. 使用未编码的斜杠
  5. 用下划线(_)代替斜杠

同样,在您的测试代码中有一个错误:

$string[2] = "t' /#%&=";

斜杠-空格不是有效的转义序列。您应该将代码更改为"t''/#%&=";为了避免反斜杠被解释为转义字符。