php中urlencode与rawurlencode的区别

本文详细介绍了PHP中的urlencode与rawurlencode函数的区别,以及JavaScript中escape与encodeURIComponent的区别,并通过代码示例进行对比说明。

前段时间说自己遇到了个《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 格式以免其被传输媒体(像一些邮件系统)使用字符转换时弄乱。下面我们来看一下例子:

 代码如下复制代码

<?php

$string = "hello world";

echo urlencode($string) . '<br/>'; //输出:hello+world
echo rawurldecode($string) . '<br/>';//输出:hello%20world

?>

具体例子比较:

 代码如下复制代码

<?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 "urlencode 不做编码的字http://www.111cn.net/符:\n".preg_replace("/%.{2}/","",urlencode($asscii));
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的区别:

 代码如下复制代码

>>>  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版的解码函数,是用手册里找的:

<?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个

来自:http://www.111cn.net/phper/php-cy/58640.htm

<think>好的,我现在需要帮助用户了解PHPurlencode函数的用法,并提供示例。首先,我要回忆一下这个函数的基本作用。根据引用资料,urlencode()主要用于对URL进行编码,特别是处理特殊字符,确保它们在URL中正确传输。比如,空格会被转换成加号+,其他非字母数字字符变成百分号加十六进制数,比如%20。 用户可能需要知道什么时候使用这个函数,比如在GET请求中传递参数时,或者处理表单数据。我需要解释清楚函数的基本语法:string urlencode(string $str),参数是待编码的字符串,返回值是编码后的字符串。 接下来,我应该举几个例子,比如编码一个带有空格和特殊字符的字符串,比如“PHP教程 & 示例”,编码后应该变成“PHP%E6%95%99%E7%A8%8B+%26+%E7%A4%BA%E4%BE%8B”。这里要注意中文字符会被编码成百分号形式,空格变加号,&符号也被编码。这符合引用3中的描述。 然后,用户可能需要知道如何在URL中使用编码后的参数。例如,构造一个带查询参数的URL,将参数值用urlencode处理,确保整个URL有效。比如,编码“search term”为“search+term”,然后拼接到URL中。 还要提到和rawurlencode区别,根据引用3,rawurlencode会把空格转为%20,而urlencode转为+。这点需要强调,因为用户可能会混淆这两个函数。例如,在处理URL路径部分时,可能需要用rawurlencode,而在查询参数中用urlencode,因为表单POST数据通常用+号。 另外,需要提醒用户常见的应用场景,比如处理表单数据、生成动态链接、API请求参数编码等。同时,注意事项,比如不要对整个URL编码,只对参数部分编码,避免重复编码导致问题。 可能用户还会遇到编码后参数解码的问题,这时候需要提到urldecode函数的使用,但根据问题描述,用户目前只问编码,所以这部分可以作为补充,但不需要详细展开。 最后,确保示例代码正确,语法无误,并且符合PHP的书写规范。比如,使用echo输出结果,变量命名清晰。同时,注意在示例中展示编码前后的对比,让用户更直观理解。 总结一下,回答的结构应该是:函数作用、语法、示例、rawurlencode区别、应用场景、注意事项。这样用户能逐步了解如何使用urlencode,并在实际开发中正确应用。</think>### PHP urlencode() 函数用法详解 #### 1. 核心作用 `urlencode()` 用于将字符串编码为合法的 URL 格式,主要处理以下字符: - 空格 → `+` 号 - 非字母数字字符 → `%` 开头的十六进制编码(如 `/` → `%2F`) - 中文等特殊字符 → UTF-8 编码后再转换(如 `教程` → `%E6%95%99%E7%A8%8B`) #### 2. 基础语法 ```php string urlencode ( string $str ) ``` ```php $raw_str = "PHP教程 & 示例"; $encoded = urlencode($raw_str); echo $encoded; // 输出:PHP%E6%95%99%E7%A8%8B+%26+%E7%A4%BA%E4%BE%8B ``` #### 3. 典型应用场景 **(1) GET 请求参数编码** ```php $query = urlencode("search term"); $url = "https://example.com/search?q=".$query; // q=search+term ``` **(2) 表单数据处理** ```php $form_data = [ 'name' => '张三', 'comment' => 'This is a test & demo' ]; $encoded_str = http_build_query($form_data); // 自动调用urlencode ``` **(3) API 参数传递** ```php $api_params = [ 'app_key' => 'AB12-CD34', 'timestamp' => time() ]; $request_url = "https://api.example.com?".http_build_query($api_params); ``` #### 4. rawurlencode() 的差异 | 函数 | 空格处理 | RFC标准 | 适用场景 | |------|---------|--------|----------| | urlencode() | `+` | 表单数据标准 | 查询参数 | | rawurlencode() | `%20` | RFC 3986 | URL路径 | ```php $path_segment = rawurlencode("user files"); // user%20files $url = "/download/".$path_segment; ``` #### 5. 注意事项 1. **双重编码问题** ```php // 错误做法 $double_encoded = urlencode(urlencode("数据")); // %25E6%2595%25B0%25E6%258D%25AE // 正确做法 $correct_encoded = urlencode("数据"); // %E6%95%B0%E6%8D%AE ``` 2. **编码范围控制 ```php $partial_url = "https://example.com/".urlencode("路径/文件"); // 错误!斜杠被编码 $valid_url = "https://example.com/".rawurlencode("路径/文件"); // 保留斜杠 ``` 3. **解码对应关系** ```php $decoded = urldecode("PHP+%26+MySQL"); // 返回 "PHP & MySQL" ``` #### 6. 高级用法示例 **处理JSON参数** ```php $filters = [ 'category' => '电子设备', 'price_range' => '1000-2000' ]; $json_params = urlencode(json_encode($filters)); // 结果:%7B%22category%22%3A%22%E7%94%B5%E5%AD%90%E8%AE%BE%E5%A4%87%22%2C%22price_range%22%3A%221000-2000%22%7D ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值