page contents

深入理解PHP内核:变量及数据类型

数据类型用来说明数据的类型,确定了数据的解释方式,同时指明了数据的长度,也就是数据占用的字节数。

attachments-2020-04-hkyrq0sf5e9e6a1b93d41.png

1、小箱子

现实生活中我们会找一个小箱子来存放物品,一来显得不那么凌乱,二来方便以后找到。

计算机也是这个道理,我们需要先在内存中找一块区域,规定用它来存放数据,并起一个好记的名字,方便以后查找。

这块区域就是“小箱子”,我们可以把数据放进去了。


2、数据类型

数据类型用来说明数据的类型,确定了数据的解释方式,同时指明了数据的长度,也就是数据占用的字节数。


3、变量

变量名就是给那块内存区域起了个名字,方便使用。


4、从类型划分

1)静态类型语言:比如c/java,类型检查在编译器确定

2)动态类型语言: 比如PHP/python,类型在运行时确定

3)无类型语言: 比如汇编语言,对类型无知


5、PHP变量类型及存储结构

PHP在声明或使用变量的时候,并不需要显式指明其数据类型。

PHP是弱类型语言,这并不表示PHP没有类型,在PHP中,存在8种变量类型。

①标量类型:boolean、integer、float(double)、string
②复合类型:array、object
③特殊类型:resource、NULL

6、PHP变量存储结构

变量的值存储到以下所示zval结构体中

typedef struct _zval_struct zval;

struct _zval_struct {

    /* Variable information */

    zvalue_value value;     /* value */

    zend_uint refcount__gc;

    zend_uchar type;    /* active type */

    zend_uchar is_ref__gc;

};

结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同。

每个这样的变量或数组都称为结构体的成员(Member),使用结构体(Struct)来存放一组不同类型的数据


7、PHP变量类型

zval结构体的type字段就是实现弱类型最关键的字段了,type的值可以为: IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_ARRAY、IS_OBJECT和IS_RESOURCE 之一。 

从字面上就很好理解,他们只是类型的唯一标示,根据类型的不同将不同的值存储到value字段。 

除此之外,和他们定义在一起的类型还有IS_CONSTANT和IS_CONSTANT_ARRAY。

这和我们设计数据库时的做法类似,为了避免重复设计类似的表,使用一个标示字段来记录不同类型的数据。

8、PHP变量的值存储

变量的值存储在zvalue_value联合体中
typedef union _zvalue_value {

    long lval;                  /* long value */

    double dval;                /* double value */

    struct {

        char *val;

        int len;

    } str;

    HashTable *ht;              /* hash table value */

    zend_object_value obj;

} zvalue_value;

结构体和联合体的区别在于:

结构体的各个成员会占用不同的内存,互相之间没有影响;

而联合体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。


结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),联合体占用的内存等于最长的成员占用的内存。

联合体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。


1)一般类型

1

宏定义是预处理命令的一种,它允许用一个标识符来表示一个字符串#define 宏名 字符串
带参数宏定义对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

2)字符串String

struct {

    char *val;

    int len;

} str;

C中字符串是以\0结尾的字符数组,这里多存储了字符串的长度,这和我们在设计数据库时增加的冗余字段异曲同工。 

因为要实时获取到字符串的长度的时间复杂度是O(n),而字符串的操作在PHP中是非常频繁的,这样能避免重复计算字符串的长度, 这能节省大量的时间,是空间换时间的做法。

这么看在PHP中strlen()函数可以在常数时间内获取到字符串的长度。 

计算机语言中字符串的操作都非常之多,所以大部分高级语言中都会存储字符串的长度。


  • 其实在C语言中没有专门的字符串类型,我们只能使用数组或者指针来间接地存储字符串。
  • 字符数组实际上是一系列字符的集合,也就是字符串(String),在C语言中,字符串总是以'\0'作为串的结束符。数组的长度要比字符串的长度(字符串长度不包括 '\0')大1。
  • 另外一种表示字符串的方法,就是直接使用一个指针指向字符串,字符串中的所有字符在内存中是连续排列的,val指向的是字符串的第 0 个字符;我们通常将第 0 个字符的地址称为字符串的首地址。字符串中每个字符的类型都是char,所以 str 的类型也必须是char *。

PHP的弱变量容器的实现方式是兼容并包的形式体现,针对每种类型的变量都有其对应的标记和存储空间。 

使用强类型的语言在效率上通常会比弱类型高,因为很多信息能在运行之前就能确定,这也能帮助排除程序错误。

而这带来的问题是编写代码相对会受制约。


1

  • 发表于 2020-04-21 11:37
  • 阅读 ( 676 )
  • 分类:PHP开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1316 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章