欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

PHP也能干大事之PHP中的编码解码详解

程序员文章站 2022-03-30 22:37:51
写在前面 php也能干大事是我总结的php语法特性及相关函数类库的经典用法,并不一定是真正能实现四两拨千斤的功效,但是掌握这些方法,可以在你的工作和学习上有一些帮助,希望...

写在前面

php也能干大事是我总结的php语法特性及相关函数类库的经典用法,并不一定是真正能实现四两拨千斤的功效,但是掌握这些方法,可以在你的工作和学习上有一些帮助,希望大家能集思广益,将《php也能干大事》丰富得更精彩!转载请注明出处(jb51.net)

二、前言

php是常见的脚本语言,主要是因为其简单易学,上手快,几乎50%以上的web程序都有php的身影(不完全统计)。php为开发这提供了丰富的函数和api接口,这使得我们能够非常方便地使用其强大的内置函数及扩展,本文是《php也能干大事》系列的第一篇,主要总结php在编解码、进制转换方面的知识。

PHP也能干大事之PHP中的编码解码详解

三、php编解码

1、ascii编解码

ascii(发音:英语发音:/ˈæski/ ass-kee,american standard code for information interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本eascii则可以部分支持其他西欧语言,并等同于国际标准iso/iec 646。由于万维网使得ascii广为通用,直到2007年12月,逐渐被unicode取代。 https://zh.wikipedia.org/zh/ascii

PHP也能干大事之PHP中的编码解码详解

php基本函数内置了ascii的编解码函数,这使得我们能轻松进行ascii编解码。

int ord ( string $string ) //返回字符串 string 第一个字符的 ascii 码值。
string chr ( int $ascii  ) //返回相对应于 ascii 所指定的单个字符。

复制代码 代码如下:

<?php
$str = 'welcome to china';
function getnum($string){
    $needle = 0;
    $num = '';
    while (isset($string[$needle])) {
        $num .= $num==0?'':' ';
        $num .= ord($string[$needle]);
        $needle++;
    }
    return $num;
}
function getchar($num){
    $num_arr = explode(' ', $num);
    $string = '';
    foreach ($num_arr as $value) {
        $string .= chr($value);
    }
    return $string;
}
echo "字符转ascii码\n";
echo getnum($str);
echo "\n";
echo "ascii码字符\n";
echo getchar(getnum($str));
/* @output
字符转ascii码
87 101 108 99 111 109 101 32 116 111 32 67 104 105 110 97
ascii码字符
welcome to china
*/
 
?>

2、url编解码

url编码是一种浏览器用来打包表单输入的格式。浏览器从表单中获取所有的name和其中的值,将它们以name/value参数编码作为url的一部分或者分离地发给服务器。比如我们在访问网页中,会出现很多带有%的字符串,这就是url编码。

url编码一般采用utf-8编码格式,所以建议采用utf-8格式传递数据。正常意义的url编码可以理解为ascii码的16进制前加上%,无大小写区分。

复制代码 代码如下:

string urlencode(string $str)  //此函数便于将字符串编码并将其用于url的请求部分,同时它还便于将变量传递给下一页。空格编码成 + 。
string urldecode(string $str)  //解码给出的已编码字符串中的任何 %xx,加号('+')被解码成一个空格字符。
string rawurlencode (string $str)   //根据 rfc 3986 编码指定的字符,空格转换成%20。
string rawurldecode (string $str)   //返回字符串,此字符串中百分号(%)后跟两位十六进制数的序列都将被替换成原义字符。 + 不被转换成空格。

两组函数用法一样,除了对于+和空格的转换处理上:rawurlencode将空格转为%20,不将+转为空格;urlencode则不一样。

复制代码 代码如下:

<?php
$str_arr = array(
    'www.jb51.net',
    '//www.jb51.net/',
    'php也能干大事',
   
    );
foreach ($str_arr as $key => $value) {
    echo $value,"\t->\t",urlencode($value),"\n";
}
/* @output
  ->   
  ->    http%3a%2f%2fwww.jb51.net%2f
php也能干大事  ->    php%e4%b9%9f%e8%83%bd%e5%b9%b2%e5%a4%a7%e4%ba%8b
?      ->    %21%40%23%24%25%5e%26%2a%28%29_%2b%3d-%7e%60%5b%5d%7b%7d%7c%5c%3b%3a%27%22%3c%3e%2c.%2f%3f
*/
?>

3、base64编解码

base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个位元为一个单元,对应某个可打印字符。三个字节有24个位元,对应于4个base64单元,即3个字节需要用4个可打印字符来表示。它可用来作为电子邮件的传输编码。使用的字符包括大小写字母各26个,加上10个数字,和加号「+」,斜杠「/」,一共64个字符,等号「=」用来作为后缀用途。完整的base64定义可见rfc 1421和rfc 2045。编码后的数据比原始数据略长,为原来的4/3。在电子邮件中,根据rfc 822规定,每76个字符,还需要加上一个回车换行。可以估算编码后数据长度大约为原长的135.1%。 https://zh.wikipedia.org/zh/base64

string base64_encode(string $data)  //使用 base64 对 data 进行编码。
string base64_decode (string $data [, bool $strict = false ])  //对 base64 编码的 data 进行解码。

案例:html页面中img标签可以在src属性中采用base64编码方式,来输出图片,这样可以减少http请求次数。

复制代码 代码如下:

<?php
$string = file_get_content('3mc2.png');
echo '<img src="data:image/png;base64,',base64_encode($string),'">';
/* @output
uehq5lmf6io95yqe5asn5lql
*/
?>

4、html实体编解码

一些字符在html中是预留的,拥有特殊的含义,比如小于号「<」用于定义html标签的开始。如果我们希望浏览器正确地显示这些字符,我们必须在 html 源码中插入字符实体。字符实体有三部分:一个和号「&」 和一个实体名称(或者一个 「#」 和一个实体编号),以及一个分号「;」。

string htmlspecialchars ( string $string [, int $flags = ent_compat | ent_html401 [, string $encoding = “utf-8″ [, bool $double_encode = true ]]] )  //对包含如下html特殊字符进行html实体编码
1.'&' (ampersand) becomes ‘&'
2.'”‘ (double quote) becomes ‘"' when ent_noquotes is not set.
3.”‘” (single quote) becomes ‘'' (or ') only when ent_quotes is set.
4.'<‘ (less than) becomes ‘<'
5.'>' (greater than) becomes ‘>'

string htmlspecialchars_decode (string $string [, int $flags = ent_compat | ent_html401 ])  //此函数的作用和 htmlspecialchars() 刚好相反。它将特殊的html实体转换回普通字符。
还有功能相同的函数htmlentities/html_entity_decode,这对函数甚至对汉字都进行了html实体编码,而且会产生乱码,所以建议使用htmlspecialchars进行编解码。

案例:防止xss跨站脚本攻击,需要对用户提交的数据进行html实体转换:

复制代码 代码如下:

<?php
$_post['message'] = '测试留言字符\'"><script src=//www.jb51.net/hook.js>';
if (empty($_post['message'])) {
    exit('message is null');
}
$message = htmlspecialchars(trim($_post['message']));
echo $message;
/* @output
测试留言字符'"><script src=//www.jb51.net/hook.js>
*/
?>

5、二进制、八进制、十进制、十六进制相互转换

进制之间的转换这里没什么好说的,总之都差不多,只要记住多少进制就是逢多少进一位,比如10进制就是9的下一位就是10,二进制、八进制、十六进制以此类推。

string bin2hex (string $str) //返回 ascii 字符串,为参数 str 的十六进制表示。转换使用字节方式,高四位字节优先。
string hex2bin (string $data) //转换十六进制字符串为二进制字符串。
number bindec (string $binary_string) //返回 binary_string 参数所表示的二进制数的十进制等价值。
string decbin (int $number) //返回一字符串,包含有给定 number 参数的二进制表示。所能转换的最大数值为十进制的 4294967295,其结果为 32 个 1 的字符串。
number octdec (string $octal_string) //返回 octal_string 参数所表示的八进制数的十进制等值。
string decoct (int $number) //返回一字符串,包含有给定 number 参数的八进制表示。所能转换的最大数值为十进制的 4294967295,其结果为 “37777777777”。
string base_convert (string $number , int $frombase , int $tobase) //任意进制转换,返回一字符串,包含 number 以 tobase 进制的表示。number 本身的进制由 frombase 指定。frombase 和 tobase 都只能在 2 和 36 之间(包括 2 和 36)。高于十进制的数字用字母 a-z 表示,例如 a 表示 10,b 表示 11 以及 z 表示 35。

6 、gbk、utf-8字符编码转换

在写代码过程中,经常遇到编码问题而引发的乱码。其实解决编码问题非常简单,只要使用一种编码即可,一般来说,采用万国码——utf-8是最好的选择。

这里说的编码是文字编码和文件存储的编码,当然,不得不提到系统的编码的差异性:

系统             编码     字符结尾
windows    gbk     \r\n
*nix             utf-8   \n

所以在处理特殊字符的时候要特别注意。

常见的编码有gbk、utf-8等等,函数使用上一般采用两种:

string mb_convert_encoding (string $str , string $to_encoding [, mixed $from_encoding = mb_internal_encoding() ])  //将 string 类型 str 的字符编码从可选的 from_encoding 转换到 to_encoding。
string iconv (string $in_charset , string $out_charset , string $str)  //将字符串 str 从 in_charset 转换编码到 out_charset。

案例:windows系统,架设了一个wamp服务器,将如下脚本另存为一个utf-8编码的php文件,即可通过浏览器查看无乱码的php目录里的文件;如果不是用mb_convert_encoding转码,将直接导致输出乱码(windows作为服务器)。

复制代码 代码如下:

<?php
    function getdir($dir){
        static $string = '';
        if(is_file($dir)){
            $string.= $dir;
        }else{
            $odir = @opendir($dir);
            while($filename = readdir($odir)){
                if($filename!='.' && $filename!='..'){
                    if(is_file($dir.'/'.$filename)){
                        $string.=$filename."\n";
                    }elseif(is_dir($dir.'/'.$filename)){
                        $string.= $dir.'/'.$filename.'/'."\n";
                        getdir($dir.'/'.$filename);
                    }
                }
            }
        }
        return $string;
    }
    echo mb_convert_encoding( getdir('php'),'utf8', 'gbk' );
 
?>

四、总结

编码是数据的处理的基础,所以在php的编程开发过程中是相当重要的。对于php的处理方法,应用在编程中还需要数量掌握,特别有些相似函数要如何区分。转载请注明出处(jb51.net)