如果我想使用变量创建URL,我有两个选择来编码字符串。 urlencode()
和rawurlencode()
。
究竟有什么区别,哪些是首选?
答案 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%20asd
与asd+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)
我认为空格必须编码为:
%20
在URL查询字符串组件或表单数据中使用时,+
(请参阅17.13.4 Form content types)以下示例显示正确使用rawurlencode
和urlencode
:
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)
不同之处在于返回值,即:
返回一个全部的字符串 除-_之外的非字母数字字符。 已被替换为百分比(%) 标志后跟两个十六进制数字和 空格编码为加号(+)。它 以与编码相同的方式编码 从WWW表单发布的数据是 编码,与in中的方式相同 应用程序/ x-WWW窗体-urlencoded 媒体类型。这与» RFC 1738编码(参见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)
唯一的区别在于处理空格的方式:
urlencode - 基于遗留实现将空格转换为+
rawurlencode - 基于RFC 1738将空格转换为%20
造成差异的原因是因为在网址中保留了+并且有效(未编码)。
我真的很想看到选择其中一个的一些理由......我希望能够选择一个并永远使用它而不用大惊小怪。
很公平,我做出这些决定时会遵循一个简单的策略,我将与您分享,希望它可以提供帮助。
我认为是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通常更兼容