前段时间说自己遇到了个《URL加号引发错误》的BUG,引起这个bug的原因就是自己在URL中使用了 urlencode 函数,该函数会把空格转换成加号,这样就导致URL解析出错,而空格只有转换成 %20 才可以可以正常解析,这时我们就需要使用 rawurlencode 函数。
下面就介绍一下 urlencode 函数与 rawurlencode 函数的区别:
urlencode 函数:
返回字符串,此字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+)。此编码与 WWW 表单 POST 数据的编码方式是一样的,同时与 application/x-www-form-urlencoded 的媒体类型编码方式一样。由于历史原因,此编码在将空格编码为加号(+)方面与 RFC1738 编码(参见 rawurlencode())不同。
rawurlencode 函数:
返回字符串,此字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数。这是在 » RFC 3986 中描述的编码,是为了保护原义字符以免其被解释为特殊的 URL 定界符,同时保护 URL 格式以免其被传输媒体(像一些邮件系统)使用字符转换时弄乱。下面我们来看一下例子:
1
2
3
4
5
6
7
8
9
|
<?php $string = "hello world" ; echo urlencode( $string ) . '<br/>' ; //输出:hello+world echo rawurldecode( $string ) . '<br/>' ; //输出:hello%20world ?> |
具体例子比较:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<?php for ( $i = 0x20; $i < 0x7f; $i ++) { $str .= dechex ( $i ); } $asscii = pack( "H*" , $str ); echo "所有的可打印的asscii字符:(从空格到~)n" . $asscii . "\n" ; echo "urlencode 的结果:\n" .urlencode( $asscii ); echo "\n" ; echo "\n" ; echo "rawurlencode 的结果:\n" .rawurlencode( $asscii ); echo "\n" ; echo "rawurlencode 不做编码的字符:\n" .preg_replace( "/%.{2}/" , "" ,rawurlencode( $asscii )); echo "\n" ; exit ; ?> 输出结果: ——————————————————————————— 所有的可打印的asscii字符:(从空格到~) !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~ urlencode 的结果: +%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E urlencode 不做编码的字符: +-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz rawurlencode 的结果: %20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E rawurlencode 不做编码的字符: -.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz |
比较二者的结果:
1. 数字、大小写字母都不编码
2. 减号、点号、下划线 三个不编码
3. rawurlencode比urlencode多编码一个”加号“
关于JavaScript中escape与encodeURIComponent的区别:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
>>> console.log(encodeURIComponent( "统一注册1" )); %E7%BB%9F%E4%B8%80%E6%B3%A8%E5%86%8C1 >>> console.log(escape( "统一注册1" )); %u7EDF%u4E00%u6CE8%u518C1 <?php echo iconv( "utf-8" , "gbk" ,urldecode( "%E7%BB%9F%E4%B8%80%E6%B3%A8%E5%86%8C1" )); echo "\n" ; echo urldecode( "%u7EDF%u4E00%u6CE8%u518C1" ); // 使用下面的unescape可以 //echo iconv("utf-8","gbk",unescape("%u7EDF%u4E00%u6CE8%u518C1"); exit ; ?> 输出结果: ====================================== 统一注册1 %u7EDF%u4E00%u6CE8%u518C1 ====================================== |
结果说明:
1. encodeURIComponent 总是把输入转换成utf8编码处理的,按字节编码
2. escape是按照unicode编码处理的,因为它也对url中不安全的字符做了编码,所以也可以在url中做编码使用,但是,服务器端不会自动解码,下面提供一个PHP版的解码函数,是用手册里找的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<?php function unescape( $str ) { $str = rawurldecode( $str ); preg_match_all( "/(?:%u.{4})|&#x.{4};|&#d+;|.+/U" , $str , $r ); $ar = $r [0]; foreach ( $ar as $k => $v ) { if ( substr ( $v ,0,2) == "%u" ) $ar [ $k ] = iconv( "UCS-2" , "UTF-8" ,pack( "H4" , substr ( $v ,-4))); elseif ( substr ( $v ,0,3) == "&#x" ) $ar [ $k ] = iconv( "UCS-2" , "UTF-8" ,pack( "H4" , substr ( $v ,3,-1))); elseif ( substr ( $v ,0,2) == "&#" ) { $ar [ $k ] = iconv( "UCS-2" , "UTF-8" ,pack( "n" , substr ( $v ,2,-1))); } } return join( "" , $ar ); } ?> >>> console.log(escape( " !\"#$%&'()*+,-./0123456789:;=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~" )); %20%21%22%23%24%25%26%27%28%29*+%2C-./0123456789%3A%3B%3C%3D%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E >>> console.log(encodeURIComponent( "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~" )); %20!%22%23%24%25%26'()*%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~ >>> console.log(escape( "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~" ).replace(/%.{2}/g, "" )); *+-./0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz >>> console.log(encodeURIComponent( "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~" ).replace(/%.{2}/g, "" )); !'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~ |
结果比较:
escape未编码的字符: *+-./@_ 共7个
encodeURIComponent未编码的字符: !'()*-._~ 共9个
以上这篇浅谈php中urlencode与rawurlencode的区别就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。