PHP为什么要用pack/unpack
博客专区 > 吾爱 的博客 > 博客详情
PHP为什么要用pack/unpack
吾爱 发表于4个月前
PHP为什么要用pack/unpack
  • 发表于 4个月前
  • 阅读 33
  • 收藏 1
  • 点赞 0
  • 评论 0

移动开发云端新模式探索实践 >>>   

pack/unpack详细用法参见:

https://my.oschina.net/goal/blog/195749?p=1#OSC_h3_12

这里只探讨一下为什么会有这两个函数,在什么情况下要用到它们。

首先,了解下php里的字符串string,一般情况下我们用字符串是用来表示一个人类可读的文本,简单来讲就是用来表示一串文字,例如:

$str = 'abc';

abc 是3个字母组成的一串文本,其实对于计算机来说,它就是一串二进制而已 01010101... ,但是为了便于代码中处理,一般是按字节为单位来处理,一个字节8位。以上面的 $str 来说,转换成字节序列就是:

[ord('a'),ord('b'),ord('c')]
// [97,98,99]

问题来了,假设我们需要跟外部服务打交道,它要求我们传一条消息,这条消息是3各字节,对应字节码分别是 97 98 99,巧了,正好对应 abc 三个字母,我们可以直接通过 $msg = 'abc'; 生成这条消息,并直接发送给外部服务。

但是,如果它要求的是 0x01 0x02 0x03 呢?(这里用的是十六进制表示),你能打出来吗?$msg = ???

这时候需要拐个弯,你可以这样写 $msg = chr(0x01).chr(0x02).chr(0x03); 在这种足够简单的情形下可以达到要求,但是不幸的是,一般网络通信中,如果是自定义协议,一般会涉及更多的数据类型并且还有大端小端问题,关于大端小端也不做详细描述,可自行搜索相关资料。

比如啊,对方要求传一条消息,这个消息由2部分组成,前两个字节固定为 0x220x33 后面紧跟一个在c语言中是无符号16位整型,并且这个整型是小端存储,好了,你可以构建这条消息:

$msg = chr(0x22).chr(0x33);
//无符号16位整型?两个字节? 小端?
$num = 0x0532; //假设这是要传的16位整型,那么怎么转换成两个字节的无符号小端字节序列?
//经过研究,了解了小端字节序的意思,可以这样构建
$msg .= chr(0x32).chr(0x05);

是不是很麻烦?这时候就可以用pack来做这个事了,一行代码搞定而已。

$msg = pack('C2v',0x22,0x33,0x0532);

是不是很方便?我们只需要了解pack第一个参数怎么设置就可以了,这里简单解释一下

'C2' 的意思是,将后面前两个参数,即 0x22 0x33 ,作为无符号char类型打包到字符串中,紧接着 'v' 的意思是,将后面的一个参数,作为无符号short类型(16位整型,两个字节,小端),打包到字符串中,最终得到一个4字节的字符串,就可以发给对方了。

unpack同理,是用来解析对方传过来的二进制字符串,前提是双方约定好打包规则,比如如果要解包上面的 $msg ,只需要

$data = unpack('C2head/vnumber',$msg);

注意,每个部分你可以用 '/' 分割,然后,每个解析规则后面都可以跟一个名字作为解析结果数组的key,最终得到

Array
(
    [head1] => 34
    [head2] => 51
    [number] => 1330 //这里php默认会以10进制的形式显示,其实等于0x0532
)
标签: PHP
  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 142
博文 255
码字总数 88909
×
吾爱
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: