当前位置: 首页 > 后端技术 > PHP

PHP中pack和unpack函数的详细用法

时间:2023-03-30 06:18:19 PHP

PHP中有两个函数pack和unpack。很多PHPer都没有在实际项目中使用过,甚至不知道这两个方法是干什么用的。本文将向您介绍它们的用途。PHP中有两个函数pack和unpack。很多PHPer都没有在实际项目中使用过,甚至不知道这两个方法是干什么用的。本文将向您介绍它们的用途。pack1`stringpack(string``$format``[,mixed``$args``[,mixed$...]])`该函数用于将对应的参数($args)打包成二进制字符串。第一个参数$format有以下几个选项(可选参数比较多,后面会选出几个常用的解释):看到这么多参数,还真是头一次看的一头雾水,大部分的解释很容易理解,但是主机的字节顺序,大端,小端等到底是什么?下面的内容比较枯燥,但是一定要看懂,坚持看下去。什么是字节顺序?它是字节的顺序。说白了就是多字节数据的存储顺序(一个字节显然不需要顺序)。例如,A和B的二进制表示分别是01000001和01000010。对于字符串AB的存储,我们既可以是0100000101000010,也可以是0100001001000001,这个顺序就是所谓的字节序。高/低字节如字符串AB,左高右低(我们正常的读取顺序),A为高字节,B为低字节高/低地址假设0x123456按照从高到低的顺序存放,内存中存放的是这样:高地址->低地址12->34->56big-endianbyteorder(网络字节序)big-endian就是把高位字节放在内存的低地址端,而低位-顺序字节在高地址端。在网络传输(如TCP/IP)中,低地址端(高字节)放在流的开头。对于一个2字节的字符串(AB),传输顺序为:A(0-7bit),B(8-15bit)。那么little-endian自然是big-endian的对立面。hostbyteorder表示当年机器的字节序(即网络字节序确定,而host字节序由机器决定),一般是littleendian。aandA(packedstrings,用NUL或空格填充)`$string``=pack(``'a6'``,'china');``var_dump(``$string``);``//输出结果:string(6)"china",最后一个字节是一个不可见的NUL``echo``ord(``$string``[5]);``//输出结果:0(ASCII码0对应nul)``//A相同``$string``=pack(``'A6'``,'china');``var_dump(``$string``);``//输出结果:string(6)"china",最后一个字节是一个空格``echo``ord(``$string``[5]);``//输出结果:32(ASCII码中的32对应空格)`handH`$string``=pack(``'H3'``,281);``var_dump(``$string``);``//输出结果:string(2)"("``for``(``$i``=0;``$i``<``strlen``(``$string``);``$i``++){``echo``ord(``$string``[``$i``]).PHP_EOL;``}``//Outputresult:4016`h和H需要特别说明,将对应的参数视为十六进制字符然后打包,什么意思,比如上面的281在打包之前会先转换为0x281,因为1个16进制对应4个b二进制数字,而上面的0x281只有1.5个Byte,默认补0变成0x2810,0x28对应的十进制值为40(()),0x10对应的十进制值为16(dle不可见字符).c和C`$string``=pack(``'c3'``,67,68,-1);``var_dump(``$string``);``//输出:string(3)"CD?"``for``(``$i``=0;``$i``<``strlen``(``$string``);``$i``++){``echo``ord(``$string``[``$i``])。PHP_EOL;``}``//输出:6768225`最终输出本能应该是6768-1ord得到字符的ASCII码(范围0-255),此时-1对应的字符(00000001)会以补码的形式输出,即255(11111110+00000001=11111111)个整数与所有整数类型相关的使用方法完全一样,只需要注意它们的位顺序和字节顺序即可。以L为例说明:`$string``=pack(``'L'``,123456789);``var_dump(``$string``);```//Output:string(4)"?["``for``(``$i``=0;``$i``<``strlen``(``$string``);``$i``++){``echo``ord(``$string``[``$i``]).PHP_EOL;``}``//输出:21205917`fandd`$string``=pack(``'f'``,12345.123);``var_dump(``$string``);``//output:string(4)"~?@F”``var_dump(unpack(``'f'``,``$string``));``//这里提前使用Unpack,后面会解释``//Output:float(12345.123046875)`f和d是为浮点数打包的,至于为什么打包前是12345.123,解包后是12345.123046875,这跟floating的存储有关系-点数。x,X,Z,@`$string``=pack(``'x'``);``//打包一个空字符串``echo``ord(``$string``);``//Output:0`关于X(大写的X),我试了N次,都没看懂怎么用。有清楚的童鞋请给我留言,谢谢。`$string``=pack(``'Z2'``,``'abc5'``);``//其实从Z后面的数字位置开始,全部设置为nul``var_dump(``$string``);```//输出:string(2)"a"``for``(``$i``=0;``$i``<``strlen``(``$string``);``$i``++){``echo``ord(``$string``[``$i``]).PHP_EOL;``}``//输出:970``$string``=pack(``'@4'``);``//我理解为填充Nnul``var_dump(``$string``);``//输出:string(4)""``for``(``$i``=0;``$i``<``strlen``(``$string``);``$i``++){``echo``ord(``$string``[``$i``])。PHP_EOL;``}``//Output:0000`unpackunpack的使用很简单,就是packpackaging对数据进行解包,使用什么参数解包就可以了。具体用法懒得说了。这里有几个小例子:`$string``=pack(``'L4'``,1,2,3,4);``var_dump(unpack(``'L4'``,``$string``));``//输出:``array``(4){``[1]=>``int(1)``[2]=>``int(2)``[3]=>``int(3)``[4]=>``int(4)``}``$string``=pack(``'L4'``,1,2,3,4);``var_dump(unpack(``'Ll1/Ll2/Ll3/Ll4'``,``$string``));``//可以指定key,使用/拆分``//输出:``array``(4){``["l1"]=>``int(1)``["l2"]=>``int(2)``["l3"]=>``int(3)``["l4"]=>``int(4)``}`这两个函数到底是做什么用的数据通信(通过二进制格式与其他语言通信)数据加密(如果不告诉第三方你的打包方式,对方解包起来会比较困难)节省空间(比如把比较大的数字存成字符串会浪费很多空间,打包成二进制格式需要4位<32位数字>)