如果我想用一个变量创建一个URL,我有两个选择来编码字符串。Urlencode()和rawurlencode()。
到底有什么不同,哪个更可取?
如果我想用一个变量创建一个URL,我有两个选择来编码字符串。Urlencode()和rawurlencode()。
到底有什么不同,哪个更可取?
当前回答
1. 到底有什么不同
唯一的区别是对待空格的方式:
基于遗留实现的Urlencode -将空格转换为+
rawurlencode -基于RFC 1738将空格转换为%20
造成这种差异的原因是因为+在url中是保留且有效的(未编码)。
2. 首选哪种?
我真的很想知道选择一个而不是另一个的一些原因……我希望能够选择一个,并永远使用它,而不是大惊小怪。
有道理,在做这些决定时,我有一个简单的策略,我将与你分享,希望它能有所帮助。
我记得是HTTP/1.1规范RFC 2616,它要求“宽容应用程序”
客户端应该容忍状态行和服务器的解析 当解析Request-Line时。
当面对这样的问题时,最好的策略总是尽可能多地消费和生产符合标准的产品。
所以我的建议是使用rawurlencode来生成符合标准的RFC 1738编码字符串,并使用urldecode来向后兼容并容纳您可能遇到的任何消费。
现在你可以相信我的话,但让我们证明一下,好吗?
php > $url = <<<'EOD'
<<< > "Which, % of Alice's tasks saw $s @ earnings?"
<<< > EOD;
php > echo $url, PHP_EOL;
"Which, % of Alice's tasks saw $s @ earnings?"
php > echo urlencode($url), PHP_EOL;
%22Which%2C+%25+of+Alice%27s+tasks+saw+%24s+%40+earnings%3F%22
php > echo rawurlencode($url), PHP_EOL;
%22Which%2C%20%25%20of%20Alice%27s%20tasks%20saw%20%24s%20%40%20earnings%3F%22
php > echo rawurldecode(urlencode($url)), PHP_EOL;
"Which,+%+of+Alice's+tasks+saw+$s+@+earnings?"
php > // oops that's not right???
php > echo urldecode(rawurlencode($url)), PHP_EOL;
"Which, % of Alice's tasks saw $s @ earnings?"
php > // now that's more like it
PHP似乎就是这么想的,尽管我从来没有遇到过有人拒绝这两种格式中的任何一种,但我想不出更好的策略来作为您的实际策略,不是吗?
nJoy !
其他回答
我相信urlencode用于查询参数,而rawurlencode用于路径段。这主要是因为路径段使用%20,而查询参数使用+。看看这个关于空格的答案:什么时候将空格编码为加号(+)或%20?
然而,%20现在也适用于查询参数,这就是rawurlencode总是更安全的原因。然而,加号往往用于用户编辑经验和查询参数的可读性很重要的地方。
注意,这意味着rawurldecode不会将+解码为空格(http://au2.php.net/manual/en/function.rawurldecode.php)。这就是为什么$_GET总是自动通过urldecode传递,这意味着+和%20都被解码为空格。
如果您希望输入和输出之间的编码和解码保持一致,并且您已经选择对查询参数始终使用+而不是%20,那么urlencode适用于查询参数(键和值)。
结论是:
路径段-总是使用rawurlencode/rawurldecode
查询参数-解码时总是使用urldecode(自动完成),编码时,rawurlencode或urlencode都可以,只是选择一个一致,特别是在比较url时。
urlencode:这与 »RFC 1738编码(见 Rawurlencode())用于历史 原因是,空格被编码为加号 (+)的迹象。
空格编码为%20 vs. +
在大多数情况下,我看到使用rawurlencode()的最大原因是因为urlencode将文本空格编码为+(加号),而rawurlencode将它们编码为常见的%20:
echo urlencode("red shirt");
// red+shirt
echo rawurlencode("red shirt");
// red%20shirt
我特别见过某些接受编码文本查询的API端点期望看到空格%20,因此,如果使用加号则失败。显然,这在不同的API实现之间是不同的,您的里程可能会有所不同。
这取决于你的目的。如果与其他系统的互操作性很重要,那么rawurlencode似乎是一条可行之路。唯一的例外是遗留系统,它希望查询字符串遵循表单编码风格,即空格编码为+而不是%20(在这种情况下,您需要urlencode)。
rawurlencode遵循PHP 5.3.0之前的RFC 1738和之后的RFC 3986(参见http://us2.php.net/manual/en/function.rawurlencode.php)
返回一个字符串,其中除-_之外的所有非字母数字字符。~被替换为百分号(%)后面跟着两个十六进制数字。这是»RFC 3986中描述的编码,用于保护文字字符不被解释为特殊的URL分隔符,并保护URL不被带有字符转换的传输媒体(如一些电子邮件系统)破坏。
注意RFC 3986 vs 1738。rawurlencode在php 5.3之前根据RFC 1738对波浪字符(~)进行编码。然而,从PHP 5.3开始,rawurlencode遵循RFC 3986,它不需要编码波浪号字符。
Urlencode将空格编码为加号(不像rawurlencode中那样%20)(参见http://us2.php.net/manual/en/function.urlencode.php)
返回一个字符串,其中除-_之外的所有非字母数字字符。已替换为百分号(%)后面跟着两个十六进制数字和编码为加号(+)的空格。它的编码方式与WWW表单中发布的数据的编码方式相同,这与application/x-www-form-urlencoded media类型的编码方式相同。这与»RFC 3986编码(参见rawurlencode())不同,因为历史原因,空格被编码为加号(+)。
这对应于RFC 1866中application/x-www-form-urlencoded的定义。
更多阅读:
您也可以在http://bytes.com/groups/php/5624-urlencode-vs-rawurlencode上查看讨论。
另外,RFC 2396也值得一看。RFC 2396定义了有效的URI语法。我们主要感兴趣的部分来自3.4查询组件:
在查询组件,字符 ";", "/", "?", ":", "@", “&”、“=”、“+”、“,”和“$”保留。
正如您所看到的,+是查询字符串中的保留字符,因此需要按照RFC 3986进行编码(与rawurlencode一样)。
1. 到底有什么不同
唯一的区别是对待空格的方式:
基于遗留实现的Urlencode -将空格转换为+
rawurlencode -基于RFC 1738将空格转换为%20
造成这种差异的原因是因为+在url中是保留且有效的(未编码)。
2. 首选哪种?
我真的很想知道选择一个而不是另一个的一些原因……我希望能够选择一个,并永远使用它,而不是大惊小怪。
有道理,在做这些决定时,我有一个简单的策略,我将与你分享,希望它能有所帮助。
我记得是HTTP/1.1规范RFC 2616,它要求“宽容应用程序”
客户端应该容忍状态行和服务器的解析 当解析Request-Line时。
当面对这样的问题时,最好的策略总是尽可能多地消费和生产符合标准的产品。
所以我的建议是使用rawurlencode来生成符合标准的RFC 1738编码字符串,并使用urldecode来向后兼容并容纳您可能遇到的任何消费。
现在你可以相信我的话,但让我们证明一下,好吗?
php > $url = <<<'EOD'
<<< > "Which, % of Alice's tasks saw $s @ earnings?"
<<< > EOD;
php > echo $url, PHP_EOL;
"Which, % of Alice's tasks saw $s @ earnings?"
php > echo urlencode($url), PHP_EOL;
%22Which%2C+%25+of+Alice%27s+tasks+saw+%24s+%40+earnings%3F%22
php > echo rawurlencode($url), PHP_EOL;
%22Which%2C%20%25%20of%20Alice%27s%20tasks%20saw%20%24s%20%40%20earnings%3F%22
php > echo rawurldecode(urlencode($url)), PHP_EOL;
"Which,+%+of+Alice's+tasks+saw+$s+@+earnings?"
php > // oops that's not right???
php > echo urldecode(rawurlencode($url)), PHP_EOL;
"Which, % of Alice's tasks saw $s @ earnings?"
php > // now that's more like it
PHP似乎就是这么想的,尽管我从来没有遇到过有人拒绝这两种格式中的任何一种,但我想不出更好的策略来作为您的实际策略,不是吗?
nJoy !