urlencode vs rawurlencode?

时间:2009-06-15 13:33:36

标签: php urlencode url-encoding

如果我想使用变量创建URL,我有两个选择来编码字符串。 urlencode()rawurlencode()

究竟有什么区别,哪些是首选?

11 个答案:

答案 0 :(得分:308)

这取决于你的目的。如果与其他系统的互操作性很重要,那么看来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.在php 5.3之前的rawurlencode根据RFC 1738编码了波形符(~)。但是,从PHP 5.3开始,rawurlencode遵循RFC 3986,不需要编码波形符。

urlencode 将空格编码为加号(而非%20,如rawurlencode中所做)(请参阅http://us2.php.net/manual/en/function.urlencode.php

  

返回一个字符串,其中除-_之外的所有非字母数字字符。已被替换为百分号(%),后跟两个十六进制数字和空格,编码为加号(+)。它的编码方式与编码WWW表单中的发布数据的方式相同,这与application / x-www-form-urlencoded媒体类型的方式相同。这与»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 Query Component:

  

在查询组件中,保留字符";", "/", "?", ":", "@",
"&", "=", "+", ",", and "$"

如您所见,+是查询字符串中的保留字符,因此需要根据RFC 3986进行编码(如rawurlencode中所示)。

答案 1 :(得分:207)

答案 2 :(得分:34)

echo rawurlencode('http://www.google.com/index.html?id=asd asd');

产量

http%3A%2F%2Fwww.google.com%2Findex.html%3Fid%3Dasd%20asd

,而

echo urlencode('http://www.google.com/index.html?id=asd asd');

产量

http%3A%2F%2Fwww.google.com%2Findex.html%3Fid%3Dasd+asd

区别在于asd%20asdasd+asd

urlencode与RFC 1738的区别在于将空格编码为+而不是%20

答案 3 :(得分:27)

选择其中一个的一个实际原因是,如果您要在其他环境中使用该结果,例如JavaScript。

在PHP urlencode('test 1')中返回'test+1',而rawurlencode('test 1')返回'test%201'作为结果。

但如果您需要使用 decodeURI()功能在JavaScript中“解码”此功能,那么decodeURI("test+1")将为您提供"test+1"decodeURI("test%201")将为您提供"test 1" {1}}结果。

换句话说,PHP中由 urlencode 编码为plus(“+”)的空格(“”)将无法通过JavaScript中的 decodeURI 正确解码。

在这种情况下,应使用 rawurlencode PHP函数。

答案 4 :(得分:20)

我认为空格必须编码为:

    在URL路径组件中使用时,
  • %20 在URL查询字符串组件或表单数据中使用时,
  • +(请参阅17.13.4 Form content types

以下示例显示正确使用rawurlencodeurlencode

echo "http://example.com"
    . "/category/" . rawurlencode("latest songs")
    . "/search?q=" . urlencode("lady gaga");

输出:

http://example.com/category/latest%20songs/search?q=lady+gaga

如果您反过来编码路径和查询字符串组件会发生什么?对于以下示例:

http://example.com/category/latest+songs/search?q=lady%20gaga
  • 网络服务器将查找目录latest+songs,而不是latest songs
  • 查询字符串参数q将包含lady gaga

答案 5 :(得分:5)

不同之处在于返回值,即:

urlencode()

  

返回一个全部的字符串   除-_之外的非字母数字字符。   已被替换为百分比(%)   标志后跟两个十六进制数字和   空格编码为加号(+)。它   以与编码相同的方式编码   从WWW表单发布的数据是   编码,与in中的方式相同   应用程序/ x-WWW窗体-urlencoded   媒体类型。这与»   RFC 1738编码(参见rawurlencode())   因为历史原因,空间   被编码为加号(+)。

rawurlencode()

  

返回一个全部的字符串   除-_之外的非字母数字字符。   已被替换为百分比(%)   标志后跟两个十六进制数字。这个   是»RFC中描述的编码   1738用于保护文字字符   从被解释为特殊URL   分隔符,以及用于保护URL   从传播中受到损害   有角色转换的媒体(比如   一些电子邮件系统)。

两者非常相似,但后者(rawurlencode)将用'%'和两个十六进制数字替换空格,这适用于编码密码等,其中'+'不是例如:

echo '<a href="ftp://user:', rawurlencode('foo @+%/'),
     '@ftp.example.com/x.txt">';
//Outputs <a href="ftp://user:foo%20%40%2B%25%2F@ftp.example.com/x.txt">

答案 6 :(得分:5)

1。究竟是什么差异和

唯一的区别在于处理空格的方式:

urlencode - 基于遗留实现将空格转换为+

rawurlencode - 基于RFC 1738将空格转换为%20

造成差异的原因是因为在网址中保留了+并且有效(未编码)。

2。哪个更好?

  

我真的很想看到选择其中一个的一些理由......我希望能够选择一个并永远使用它而不用大惊小怪。

很公平,我做出这些决定时会遵循一个简单的策略,我将与您分享,希望它可以提供帮助。

我认为是HTTP / 1.1规范RFC 2616要求Tolerant applications

  

客户端在解析状态行和服务器时应该是宽容的      解析请求行时容忍。

面对这些问题时,最好的策略是尽可能多地使用并生成符合标准的内容。

所以我的建议是使用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!

答案 7 :(得分:4)

  

urlencode:这不同于   »RFC 1738编码(参见   rawurlencode())用于历史   原因,空格编码为加号   (+)标志。

答案 8 :(得分:1)

我认为urlencode用于查询参数,而rawurlencode用于路径段。这主要是由于路径段的%20与查询参数的+。请参阅以下有关空格的答案:When to encode space to plus (+) or %20?

然而%20现在也适用于查询参数,这就是rawurlencode总是更安全的原因。但是,在编辑用户体验和查询参数可读性很重要的情况下,往往会使用加号。

请注意,这意味着rawurldecode不会将+解码为空格(http://au2.php.net/manual/en/function.rawurldecode.php)。这就是$ _GET始终自动通过urldecode的原因,这意味着+%20都被解码为空格。

如果您希望输入和输出之间的编码和解码保持一致,并且您已选择始终使用+而不是%20作为查询参数,则urlencode可用于查询参数(键和值)。

结论是:

路径段 - 始终使用rawurlencode / rawurldecode

查询参数 - 用于解码总是使用urldecode(自动完成),对于编码,rawurlencode或urlencode都很好,只需选择一个就可以保持一致,特别是在比较URL时。

答案 9 :(得分:1)

空格编码为%20+

我在大多数情况下看到使用rawurlencode()的最大原因是因为urlencode将文本空间编码为+(加号)rawurlencode对其进行编码作为常见的%20

echo urlencode("red shirt");
// red+shirt

echo rawurlencode("red shirt");
// red%20shirt

我已经专门看到某些接受编码文本查询的API端点希望看到空格%20,因此如果使用加号则会失败。显然,这在API实现之间会有所不同,您的里程可能会有所不同。

答案 10 :(得分:0)

简单 * rawurlencode路径 - 路径是&#34;?&#34;之前的部分。 - 空格必须编码为%20 * urlencode查询字符串 - 查询字符串是&#34;?&#34;之后的部分。 - 空间被更好地编码为&#34; +&#34; = rawurlencode通常更兼容