美文网首页
php7字符串底层实现

php7字符串底层实现

作者: code_nerd | 来源:发表于2019-01-06 09:36 被阅读0次

本篇为《php7底层设计与源码实现》的读书笔记
php7 的字符串以zend_string 为载体,实现字符串的功能,还提供性能高效的smart_str

zend_string的结构体

struct  _zend_string{
  zend_refcounted_h gc;
  zend_ulong h;
  size_t len;
  char val[1];
}
  • gc 用作引用计数
  • h 哈希值,存储字符串对应的哈希值,方便在操作的时候,直接读取
  • len 存储字符串长度
  • val 柔性数组,存储字符串值的地址

h 和 len 体现了空间换时间的做法。

zend_string 的api

zend_string_init 将一个普通的字符串初始化成zend_string。
zend_string_extend 对字符串进行扩容。

  • 当扩容的字符串为普通字符串且refcount为1,直接调用perealloc进行扩容。
  • 扩容的字符串refcount大于1 或者 为内部字符串,则先申请一块内存,把值拷贝到申请的内存。对于普通字符串,还需要对老字符串把refcount 减1。

字符串的二进制安全

传统的c字符串,在取值的时候,在遇到'\0'的时候,默认遇到字符串结束了。而在php中,因为存储了字符串的长度,所以会根据字符串长度来取值,还原字符串的内容。不会因为字符串中含有'\0'而提前结束。因而可以在字符串中存储各种格式的数据。

smart_str

type_def struct{
  zend_string *s;
  size_t a;
} smart_str;

当对字符串内容需要频繁扩容的时候。php提供了一种新的结构来处理。
通过一次性申请足够大的空间,保证在修改字符串的时候,尽量不需要重新申请空间。一般如果字符串len <256 则申请256,如果len>256则申请大于len 且为4096的最小整数倍内存。通过空间换时间,避免每次修改都需要取申请或者释放内存

字符串的赋值与写时分离

zend_string中有refcount用来做计算。当字符串被引用的时候,则用zend_reference 来使在字符串内容不变的情况下,只保存一份zend_string。具体实现如下图


字符串赋值 字符串引用

字符串类型

几个概念

  • 字面量 代码中写死的变量值
  • 标识符 变量名、函数名、方法名、类名
  • php已知字符串 保留字
  • 保留字 无法用作函数名、类名等关键字 如 class public

php源码为了实现对字符串管理,对字符串进行分类。

  • IS_STR_PERSISTENT php的已知字符串,php代码中的字面量,标识符等字符串。开启opcache时,会常驻内存,如果未开启opcache则随着请求结束而被回收。
  • IS_STR_INTERNED 内部字符串

字符串类型转换

一般类型转换有两种隐式转换和显式转换
隐式转换由语言自身自动完成

  • 直接的变量赋值操作 当把字符串类型的数据赋予一个变量,不管之前这个变量的类型是什么,此时该变量就是一个字符串变量。
  • 运算式结果对变量的赋值操作 当表达式的操作数为同一数据类型,则只是改变表达式的结果,当表达式的操作数为不同数据类型,则会发生类型的自动转换。

显式类型转换
通过使用函数 或者是语言结构,完成对数据类型的转换。
如 (int) (float) 或者是 gettype settype函数

相关文章

  • php7字符串底层实现

    本篇为《php7底层设计与源码实现》的读书笔记php7 的字符串以zend_string 为载体,实现字符串的功能...

  • iOS stringWithFormat中%@的占位原理

    我们先实现几个string看看底层实现 clang之后观察具体实现 通过这4组对照可以看出,字符串在底层会被构造成...

  • 实现一个PHP的C扩展 [入门篇]

    最近想尝试写PHP的C扩展,在《PHP7底层设计与源码实现》书中有一个PHP扩展的例子,这里动手实现了一下。 准备...

  • java知识整理-从String开始

    字符串拼接 "+"的实现 两个字符串"+"的底层实现是StringBuilder,通过javap -c命令反编译代...

  • redis

    redis Redis 数据结构和底层实现string:简单动态字符串SDS,Redis 的字符串是动态字符串,是...

  • String,StringBuilder和StringBuffe

    String:字符串常量,底层实现由final char[] 存储字符串,由于被final修饰,每次增删操作都需要...

  • Redis-第九章节-动态字符串

    目录 概述 SDS(动态字符串) SDS(动态字符串)与c语言字符串的区别 1、概述 String类型底层实现的简...

  • Redis' strings

    Redis字符串基本操作命令 底层实现 Redis中,字符串对象是一个基础对象,所有键值均是字符串对象。Redis...

  • 静态链表

    看 PHP7 底层源码的书,其中提到 PHP7 的数组使用逻辑链表在进行维护,所谓逻辑链表,就是不再使用指针进行管...

  • redis底层数据实现及应用场景

    redis数据类型及底层实现 redis全局哈希表 String 底层数据结构: 简单动态字符串 应用场景: 缓存...

网友评论

      本文标题:php7字符串底层实现

      本文链接:https://www.haomeiwen.com/subject/mdgjrqtx.html