发表时间:2015-05-27来源:网络
本文主要从三个角度来阐述php的二进制安全:1. 什么叫php的二进制安全;2. 什么结构确保了php的二进制安全;3. 这种结构还有哪些其它方面的应用?
做到知其然,也知其所以然。
一句话解释:
php的内部函数在操作二进制数据时能保证达到预期的结果,例如str_replace、stristr、strcmp等函数,我们就说这些函数是二进制安全的。
举个列子:
我们来对比一下C和php下的strcmp函数。
C代码如下
main(){ char ab[] = "aa/0b"; char ac[] = "aa/0c"; printf("%d/n", strcmp(ab, ac)); printf("%d/n", strlen(ab)); }
结果:
0
2
解读:
也就是说C语言认为ab和ac这两个字符串是相等的,而且ab的长度为2.
php代码如下
结果:int(-1)
int(4)
解读:
也就是php语言认为ab和ac这两个字符串是相等的,而且ab的长度为4。
聪明的你,应该已经发现问题在哪了吧,不错,对于c语言‘/0’是字符串的结束符,所以在C语言中对于字符串“aa/0b”,它读到'/0'就会默认字符读取已经结束,而抛掉后面的字符串'b',导致我们看到strlen(“aa/0b”)的值为2
那问题又来了,php都是C来开发的,为什么php做到了二进制安全呢?
先来看看php的变量存储zval结构

php会根据type的值来决定访问value的哪个成员,为字符串时,我们会访问红框标识的str结构,这便是底层字符串的存储结构,它有两个值,一个是指向字符串的指针val,另一个是记录字符串长度的len值,就是因为有len这个值,导致了php是二进制安全的:因为它不需要像C一样通过是否遇到'/0'结尾符来判断整个字符串是否读取完毕,而是通过len这个值指定的长度进行读取。
struct sdshdr { // 记录 buf 数组中已使用字节的数量 // 等于 SDS 所保存字符串的长度 int len; // 记录 buf 数组中未使用字节的数量 int free; // 字节数组,用于保存字符串 char buf[];};可以看到,我们又见到了熟悉的len值,又是它保证了redis的存储是二进制安全的C 字符串中的字符必须符合某种编码(比如 ASCII),并且除了字符串的末尾之外,字符串里面不能包含空字符,否则最先被程序读入的空字符将被误认为是字符串结尾 ――这些限制使得 C 字符串只能保存文本数据,而不能保存像图片、音频、视频、压缩文件这样的二进制数据。
举个例子,如果有一种使用空字符来分割多个单词的特殊数据格式,如图 2-17 所示,那么这种格式就不能使用 C 字符串来保存,因为 C 字符串所用的函数只会识别出其中的"Redis" ,而忽略之后的 "Cluster" 。

虽然数据库一般用于保存文本数据,但使用数据库来保存二进制数据的场景也不少见,因此,为了确保 Redis 可以适用于各种不同的使用场景,SDS 的 API 都是二进制安全的(binary-safe):所有 SDS API 都会以处理二进制的方式来处理 SDS 存放在buf 数组里的数据,程序不会对其中的数据做任何限制、过滤、或者假设 ――数据在写入时是什么样的,它被读取时就是什么样。
这也是我们将 SDS 的 buf 属性称为字节数组的原因 ――Redis 不是用这个数组来保存字符,而是用它来保存一系列二进制数据。
比如说,使用 SDS 来保存之前提到的特殊数据格式就没有任何问题,因为 SDS 使用 len 属性的值而不是空字符来判断字符串是否结束,如图 2-18 所示。
buf"]; buf [label = " { 'R' | 'e' | 'd' | 'i' | 's' | '//0' | 'C' | 'l' | 'u' | 's' | 't' | 'e' | 'r' | '//0' | '//0' } "]; // sdshdr:buf -> buf;}">
通过使用二进制安全的 SDS ,而不是 C 字符串,使得 Redis 不仅可以保存文本数据,还可以保存任意格式的二进制数据。
上一篇:php分页代码简单实现
下一篇:PHP之文件的锁定、上传与下载
CI框架连接数据库配置操作以及多数据库操作
asp 简单读取数据表并列出来 ASP如何快速从数据库读取大量数据
C语言关键字及其解释介绍 C语言32个关键字详解
C语言中sizeof是什么意思 c语言里sizeof怎样用法详解
PHP中的魔术方法 :__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep,
PHP中的(++i)前缀自增 和 (i++)后缀自增
将视频设置为Android手机开机动画的教程
最简单的asp登陆界面代码 asp登陆界面源代码详细介绍
常用dos命令及语法
PHP中include和require区别之我见
溧阳论坛触屏版手机版下载v5.4.2.18 安卓版
68.37MB |生活服务
保利悠悦荟最新版app2026下载v3.1.6 安卓版
35.73MB |生活服务
i泰达官方版下载v2.0.10 安卓版
66.01MB |生活服务
与糖医护手机版下载v4.2.0 安卓版
46.54MB |生活服务
智慧宫翻译阿拉伯语手机版下载v1.91.0 安卓版
50.68MB |生活服务
专注清单app下载v15.9 安卓版
42.61MB |生活服务
物性表手机版下载v2.3.0 安卓版
71.12MB |商务办公
hooli留学公寓app下载v5.6.1 安卓官方版
28.64MB |生活服务
2014-09-05
2022-03-20
2022-03-21
2022-03-24
2014-09-05
2014-09-05
2015-07-05
2014-09-05
2022-03-21
2014-09-05