别这么说,看过《平凡的世界》么,平凡的字符串也可以有不平凡的故事。试看:
(1) 在C语言中,strlen计算字符串的时间复杂度是?PHP中呢?
(2) 在PHP中,怎样处理多字节字符串?PHP对unicode的支持如何?
同样是字符串,为什么c语言与C++/PHP/Java的均不相同?
数据结构决定算法,这句话一点不假。
那么我们今天就来掰一掰,PHP中的字符串结构,以及相关字符串函数的实现。
一、 字符串基础
字符串可以说是PHP中遇到最多的数据结构之一了(另外一个比较常用的是数组,见PHP内核探索之变量(4)- 数组操作)。而由于PHP语言的特性和应用场景,使得我们日常的很多工作,实际上都是在处理字符串。也正是这个原因,PHP为开发者提供了丰富的字符串操作函数(初步统计约有100个,这个数量相当可观)。那么,在PHP中,字符串是怎样实现的呢?与C语言又有什么区别呢?
1. PHP中字符串的表现形式
在PHP中使用字符串有四种常见的形式:
(1) 双引号
这种形式比较常见:$str=”this is \0 a string”; 而且以双引号包含的字符串中可以包含变量、控制字符等:$str = "this is $name, aha.\n";
(2) 单引号
单引号包含的字符都被认为是raw的,因此不会解析单引号中的变量,控制字符等:
$string = "test";
$str = 'this is $string, aha\n';
echo $str;
(3) Heredoc
Heredoc比较适合较长的字符串表示,且对于多行的字符串表示更加灵活多样。与双引号表示形式类似,heredoc中也可以包含变量。常见的形式是:
$string ="test string";
$str = <<<STR
This is a string \n,
My string is $string
STR;
echo $str;
(4) nowdoc(5.3+支持)
nowdoc和heredoc是如此的类似,以至于我们可以把它们当做是一对儿亲兄弟。nowdoc的起始标志符是用单引号括起来的,与单引号相似,它不会解析其中的变量,格式控制符等:
$s = <<<'EOT'
this is $str
this is \t test;
EOT;
echo $s;
2. PHP中字符串的结构
之前提到过,PHP中变量是用Zval(PHP内核探索之变量(1)Zval)这样一个结构体来存储的。Zval的结构是:
struct _zval_struct {
zvalue_value value; /* value */
zend_uint refcount__gc; /* variable ref count */
zend_uchar type; /* active type */
zend_uchar is_ref__gc; /* if it is a ref variable */
};
而变量的值是zvalue_value这样一个共用体:
typedef union _zvalue_value {
long lval;
double dval;
struct { /* string */
char *val;
int len;
} str;
HashTable *ht;
zend_object_value obj;
} zvalue_value;
我们从中抽取出字符串的结构:
struct {
char *val;
int len;
} str;
现在比较清楚了,PHP中字符串在底层实际上是一个结构体,该结构体包含了指向字符串的指针和该字符串的长度。
那么为什么这么做呢?换句话说,这样做有什么好处呢?我们接下来,将PHP的字符串与C语言的字符串做一个对比,以解释采用这样一种结构来存储字符串的优势。
3. 与c语言字符串的比较
我们知道,在c语言中,一个字符串可以用两种常见的形式存储,一种是使用指针方式,另一种是使用字符数组。我们接下来的说明,都以c语言的字符数组的方式来存储字符串。
(1) PHP字符串是二进制安全的,而C字符串不是。
我们经常会提到”二进制安全”这一术语,那么二进制安全究竟是什么意思呢?
wikipedia中对二进制安全(Binary Safe)的定义是:
Binary-safe is a computer programming term mainly used in connection with string manipulating functions.
A binary-safe function is essentially one that treats its input as a raw stream of data without any specific format.
It should thus work with all 256 possible values that a character can take (assuming 8-bit characters).
翻译过来就是:
二进制安全是计算机编程的术语,主要用于字符串操作函数。一个二进制安全的函数,本质上是指它将输入看做是原始的数据流(raw)而不包含任何特殊的格式。
那么为什么C字符串不是二进制安全的?我们知道,在C语言中,以字符数组表示的字符串总是以\0结尾的,这个\0便是C字符串的specific format, 用于标识字符串的结束。更近一步说,如果一个字符串中本身包含了\0且并不是该字符串的结尾,那么在C中,\0后面的所有数据都会被忽略(感觉就像是 字符串被莫名其妙的截断了)。这也意味着,C字符串只合适保存简单的文本,而不能用于保存图片、视频、其他文件等二进制数据。而在PHP中,我们可以使用$str = file_get_contents(“filename”);保存图片、视频等二进制数据。
(2) 效率对比。
企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:潜江网站建设 http://qianjiang.45qun.com
上一篇:.Net组件程序设计之线程、并发管理(一)
下一篇:最后一页