PHP 中的二进制安全
二进制安全是什么
先看一段代码:
1<?php
2
3$string1 = "Hello";
4$string2 = "Hello\0Hello";
5
6// 返回0, 由于是非二进制安全,误判为相等
7echo strcoll($string1, $string2);
8
9// 返回<0,不相等
10echo strcmp($string1, $string2);
这是为什么呢?PHP 是基于 C 实现的,PHP 代码都会被 Zend引擎编译成 opcode,最终作为 C语言去执行。而对于 C语言中 “\0” 是字符串的结束符,它读到 “\0” 就会默认字符读取已经结束,从而抛掉后面的字符串。
1main(){
2 char ab[] = "Hello";
3 char ac[] = "Hello\0Hello";
4
5 // 返回0, 由于是非二进制安全,误判为相等
6 strcmp(ab, ac);
7}
有一个二进制安全的定义:
程序不会对其中的数据做任何限制、过滤、或者假设 —— 数据在写入时是什么样的,它被读取时就是什么样。
PHP是如何实现二进制安全的
既然 PHP 是基于 C 实现的,C 字符串类型不是二进制安全的,PHP 又是如何实现的呢?这就是数据结构的功劳了。 PHP 的内核中,是如此定义字符串类型的
1struct{
2 char *val;
3 int len;
4} str;
val
是指向字符串内存的指针,len
表示该字符串的长度,无论是否遇到 “\0” 字符,C 都按照 len
长度读取该字符串。