php 二进制缓存,PHP的二进制处理

0?wx_fmt=jpeg最近从网上获取到一份IP地理位置文件库,但其采用二进制格式保存,且其中的解析语言为PHP,由此想到不如借此机会总结下PHP的二进制处理。

PHP作为Web开发的上层语言,使用二进制的场景不是很多,故在平时开发中很少接触。但正因如此,一旦接触,多数PHP开发人员多是一脸懵逼。关于其使用场景本人不敢多妄言,涉及过的有数据存储,使用PHP解析二进制存储的文件库,如引言部分的IP地理位置库

服务调用,服务间调用采用二进制协议,如语言无关的RPC通信框架thrift

二进制多使用在较为底层的服务,传输高效,解析速度快。缺点是不便于调试与扩展。

本文是关于PHP的二进制处理,但在此之前先简单介绍一些较为基础的计算机知识。

二进制

二进制是采用0和1两个符号表示数值的一种形式,个人认为其可理解为计算机的母语,是计算机发展的基础。下面列举些二进制与十进制的数值对应 01=>1 10=>2 11=>3

二进制的最小单位,即是计算机的最小单位,为比特bit。由8个bit组成的单位是1字节byte。除了比特bit与字节byte外,在计算机中还有一个字长单位,视硬件与操作系统而定,当然主要是由CPU决定。在之前很长一段时间我们使用的计算机字长都是32bit,即4个字节,现在多为64bit,即8个字节。

字节顺序

为什么要谈字节顺序?

首先并非所有单位存储对象都为一个字节可表示,如short类型需2个字节,int类型需4个字节等。那此处便会引出一个问题,多字节存储对象字节顺序是如何呢?假设有一个int类型数据0x12345678。

大端模式

存储字节顺序可能如下addr0x00000x00040x00080x0012data0x120x340x560x78

此时存储方式为高位低地址,高位数在低位地址。即我们常说的大端模式,符合我们的阅读习惯。

小端模式

当然也可能相反顺序,即可能如下addr0x00000x00040x00080x0012data0x780x560x340x12

此时存储方式为高位高地址,高位数在高位地址。即我们常说的小端模式

网络字节序

无论大端小端,对于我们都不是那么重要。只要规则定好,顺序并非那么重要。当然这仅限单机,当多台计算机间网络通信时,我们就需关注这种差异。

因我们并不知道互相通信计算机间大小端模式,所以规定在网络上传输的数据统一为大端模式,又称为网络字节序。此种方式可防止不同计算机间的差异。

PHP的pack与unpack

关于PHP的二进制处理,当然就要提到pack和unpack函数,这是PHP中用来打包和解包二进制的两个函数。

函数介绍// 二进制打包函数

string pack(string $format [, mixed $args [, mixed $... ]]) // 二进制解包函数

string unpack(string $format, string $args)

参数$format是我们重点需要理解的参数,下面逐一介绍各种格式

a 以null字符填充空白字符,即0x00 A 以空格字符填充空白字符,即0x20

示例如下<?php $a = pack("a4", "tt");$b = pack("A4", "ss");echo bin2hex($a) . PHP_EOL;echo bin2hex($b) . PHP_EOL;print_r(unpack("a4str", $a));print_r(unpack("A4str", $b));

返回结果如下:6100000062202020Array(    [str] => a)Array(    [str] => b)

首先a和b分别以a4和A4格式,其中4表示数据占据4个字节,结果61为a,62为b,此处打包数据不足4个字节,a与A分别以null字符和space字符填充。unpack采用同样规则,便可对二进制数据解包。h   十进制数作为十六进制字符串,如10即为0x10,低位在前以半字节为单位H   十进制数作为十六进制字符串,如10即为0x10,高位在前以半字节为单位

这个规则有点拗口,直接看示例解释结果<?php $a = pack("h2", 0x51);$b = pack("H2", 0x51);echo bin2hex($a) . PHP_EOL;echo bin2hex($b) . PHP_EOL;

输出结果为1881

h与H这两个规则究竟是如何的呢?首先我们将0x51转化为十进制数据,即为81.h为低位在前即为18,H为高位在前即为81。同样可采用unpack实现解包,这里不再赘述。

继续往下看其他格式类型s   有符号短整型(16位, 主机字节序)S   无符号短整型(16位, 主机字节序)n   有符号短整型(16位, 大端字节序)v   无符号短整型(16位, 小端字节序)

我们可以利用上面的format,判断本地的大小端<?php $a = pack("s", 0x5223) . PHP_EOL;$b = pack("n", 0x5223) . PHP_EOL;$c = pack("v", 0x5223) . PHP_EOL;if ($a === $b){    echo "小端" . PHP_EOL;}elseif ($a === $c){    echo "大端" . PHP_EOL;}

本人电脑输出为“大端”,由此可以判断计算机的大小端。当然这不是什么好方法。

还有更多使用格式规则,就不一一介绍了,有兴趣的朋友可多多实验尝试c   转为有符号charC   转为无符号chari   有符号整数(依赖机器大小及字节序)I   无符号整数(依赖机器大小及字节序)l   有符号整型(32位, 主机字节序)L   无符号整数(32位, 主机字节序)N   无符号长整型(32位, 大端字节序)V   无符号长整型(32位, 小端字节序)q   有符号长长整型(64位, 主机字节序)Q   无符号长长整型(64位, 主机字节序)J   有符号长长整型(64位,大端字节序)P   有符号长长整型(64位,小端字节序)f   单精度浮点型 (依赖机器大小范围)d   双精度浮点型 (依赖机器大小范围)

总的来说,PHP的二进制处理函数,就是将我们平时常用的功能进行封装,提高二进制处理的工作效率。而不用像在C语言中,使用memcpy,memset,strlen或者<>右移之类的操作实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值