文档章节

PHP为什么要用pack/unpack

吾爱
 吾爱
发布于 01/15 12:41
字数 844
阅读 49
收藏 2
PHP

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
)

© 著作权归作者所有

共有 人打赏支持
吾爱
粉丝 142
博文 265
码字总数 89754
作品 0
后端工程师
PHP: pack/unpack补遗

pack/unpack的介绍和使用加上这篇就第三篇了。确实知识点比较多,这篇算是收尾之作吧。仔细去文档上看pack/unpack的格式化字符说明,就会发现s, S, i, I, l, L, f, d都没有对应的大端序和小端...

陈亦
2014/02/23
0
11
PHP: chr和pack、unpack那些事

PHP是一门很灵活的语言。正因为它太灵活了,甚至有些怪异,所以大家对它的评价褒贬不一。其实我想说的是,任何一门语言都有它自身的哲学,有它存在的出发点。PHP为Web而生,它以快速上手、快...

陈亦
2014/02/23
0
31
php pack 和 unpack 函数

输出: PHP php 用unpack 函数后得到的就是那3个数作为键值的数组,那怎么把这个数组当作pack函数的三个参数传进去 我用了eval 函数,但是结果是false,厉害的帮忙解决下,不胜感激,像这种参...

李佳顺
2014/01/08
305
4
Linux安装jdk出现java/lang/NoClassDefFoundError

java -version Error occurred during initialization of VM java/lang/NoClassDefFoundError: java/lang/Object 检查lib目录下的tools是否是tools.pack格式(即lib/tools.pack)和 jre/lib目......

squanchao
2016/12/09
5
0
msgpack 真的比 protobuf buffers 快 4 倍吗?

hprose serialize Runtime:0.2334s json encode Runtime:15.2883s serialize Runtime:0.7090s msgpack_pack Runtime:0.6883s hprose unserialize Runtime:0.5439s json decode Runtime:24.29......

andot
2015/04/18
3.4K
4

没有更多内容

加载失败,请刷新页面

加载更多

原型模式

1、原型模式-定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 克隆(浅度克隆->拷贝值类型或者引用,深度克隆->创建新的对象,开辟新的内存) 例如客户端知道抽象Pro...

阿元
今天
6
0
awk命令扩展使用操作

awk 中使用外部shell变量 示例1 [root@centos01 t1022]# A=888[root@centos01 t1022]# echo "" | awk -v GET_A=$A '{print GET_A}'888[root@centos01 t1022]# echo "aaaaaaaaaaaaa" | aw......

野雪球
今天
13
0
深入解析MySQL视图VIEW

Q:什么是视图?视图是干什么用的? A:视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。   通过视图,可以展现基表的部分数据;...

IT--小哥
今天
18
0
虚拟机学习之二:垃圾收集器和内存分配策略

1.对象是否可回收 1.1引用计数算法 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时候计数器值为0的对象就是不可能...

贾峰uk
今天
12
0
smart-doc功能使用介绍

smart-doc从8月份底开始开源发布到目前为止已经迭代了几个版本。在这里非常感谢那些敢于用smart-doc去做尝试并积极提出建议的社区用户。因此决定在本博客中重要说明下smart-doc的功能,包括使...

上官胡闹
昨天
22
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部