http://www.nowamagic.net/librarys/veda/special/PHP%E5%86%85%E6%A0%B8%E6%8E%A2%E7%B4%A2

关注PHP 源代码 Zend\zend.h
------------------------------------------------------
变量的值由一个结构体构成
struct _zval_struct{ zvalue_value value; /*变量的值 */
zend_uint refcount_gc;/*指向的次数*/
zend_uchar type; /*变量类型*/
zend_uchar is_ref_gc;/*是否引用*/ } type字段值为以下常量(8种数据类型)
IS_NULL,IS_BOOL,IS_LONG,IS_DOUBLE
IS_STRING,IS_ARRAY,IS_OBJECT,IS_RESOURCE
----------------------------------
zvalue_value:类型的结构union typedef union _zvalue_value{ long lval double dval struct{
char *
int len;
}str; HashTable * ht; //数组类型 zend_object_value obj;
} zvalue_value; PHP中有8种数据类型,为什么zvalue_value->value联合体中,只有5种?
答:
1:NULL直接zval->type=IS_NULL,就可以表示不必设置vaLue的值
2:BOOL型 ,zval->type=IS_BOOL,再设置 zval.value.lval=1/0
3:Resoure型,资源型,往往是服务器上打开的一个接口,如 文件读取接口
zval->type=IS_RESOURCE,zval.value.lval=服务器上打的接口的编号 PHP字符串类型,长度是已经缓存的,调用STRLEN 时系统可直接返加其长度,不必计算 ----------------------------------------
zvalue_zvalue: 值内容
lval
dval
struct str
*ht
obj type: 值类型 refgc_count is_ref_gc
----------------------------------------------
php底层变量的实现
eg:
<?php $a=3; /*
{ union_zvalue{long 3}
type IS_LONG
refcount_gc:1
is_ref_gc:0
} */ $b='hello'
/* { {char:'hello'
len:5
} type:IS_STRING
refcount_gc:1
ls_ref_gc:0 } */
> --------------------------------------------------------------------- 符号表:symbol_table 符号表是一张哈希表,里面存储了变量名->变量的ZVAL结构体的地址
zeng/zend_globals.h中的HashTable symbol_table定义 eg:
<?php $a=3
$b=4.321
$c='hello'; /*****
生成了3个结构体,
同时,全局符号表中,多了3条记录
a----->0x123---->结构体{3}
b----->ox21d---->结构体{4.321}
c----->0x3A0---->结构体{HELLO}
***/ > 变量的赋值与引用 <?php $a=3;
$b=$a; /*****
产生一个结构体 ****
/ ------------------------------------------------------
当变量a赋值
$a=3
当前结构体:
zvalue:3
type:IS_LONG
refcont_gc:1
is_ref_gc:0 当变量$a给$b赋值时
$b=$a 结构体变为:
zvalue:3
type:IS_LONG
recount_gc:2
is_ref_gc:0 这样没有发声结构体复制,省空间,
两个变量指向同一个结构体,refcount_gc值从1变为2 -----------------------------------------------------
写时复制copy on write <?php $a=3;
$b=$a; /*****
产生一个结构体 ****/ $b=5
/**** 符号表中$a指向下面结构体
zvalue:3
type:IS_LONG
recount_gc:1
is_ref_gc:0
---------------------------------------------------------------------
符号表$b,指向另外一个结构体(一开始共用,到某一方要修改值时才分裂:copy on write)
zvalue:5
type:IS_LONG
recount_gc:1
is_ref_gc:0 ****/ echo $a,$b;3,5 没有干扰到对方
------------------------------------------- 引用复制特点
引用时,is_ref_gc=1,说是这个结构体与变量是引用关系,改的时候,不分裂
直接修改什,所有指向此结构体的变量,值都变化 EG:
$a=3 zvalue:3
type:IS_LONG
refcount_gc:1
is_ref_gc:0 当$b=&a //引用 $b与$a同时指向一个结构体
zvalue:3
type:IS_LONG
refcount_gc:2
is_ref_gc:1 $b=5 :结构体不分裂
结构体还是如下 zvalue:3
type:IS_LONG
refcount_gc:2
is_ref_gc:1
-----------------------------------------------------------------------
<?php
//强制分裂 $a=3; /***
{
value:3
refcount_gc:1
is_ref_gc:0
}
**/ $b=$a; /***
{
value:3
refcount_gc:2
is_ref_gc:0 }
**/ $c=&a;
//不会是如下这样变,否则,$b将会受干扰
/***
{
value:3
refcount_gc:3
is_ref_gc:1 }
**/ //如果ls_ref_gc 0->的过程中,recount_gc>1,将会强制分裂
$b分烈一份结构体
{ value:3
refcount_gc:1
is_ref_gc:0 } $a,$c结构体如下
{
value:3
refcount_gc:2
is_ref_gc:1
} $c=5 echo $a,$b,$c 5,3,5
------------------------------------------------------------------- <?php
$arr=array(0,1,2,3);
$tmp=$arr; $arr[1]=11;
echo $tmp[1]; //1 分析:
$arr=array(0,1,2,3)
结构体: zvalue:*ht ---------->0 addr1------->zval:0
type:IS_ARRAY 1 addr2-------->zval:1
refcount_gc:1 2 addr3--------->zval:2
is_ref-gc:0 3 addr4---------zval:3
|
|
$tmp=$arr----------------- $tmp 结构体
zvalue:*ht
type:IS_ARRAY
refcount_gc:2
is_ref-gc:0 --------------------------------------------------------------------
$arr[1]=11 此时结构 zvalue:*ht ---------->0 addr1------->zval:0
type:IS_ARRAY 1 addr2-------->zval:11
refcount_gc:1 2 addr3--------->zval:2
is_ref-gc:0 3 addr4---------zval:3 些时的$tmp结构: zvalue:*ht ---------->0 addr1 //指向arr
type:IS_ARRAY 1 addr2-------->zval:1(自已创建的)
refcount_gc:1 2 addr3 //指定arr
is_ref-gc:0 3 addr4 //指定arr -------------------------------------------------------------------------------------------- $arr=array(0,1,2,3)
$x=&arr[1];
$tmp=$arr; $arr[1]=999
echo $tmp[1] //999
------------------------------------------------------ 查看PHP函数的C语言实现:
cd php-src
查找 grep -rn "PHP_FUNCTION(socket_accept)" ./ext
返回 ./ext/sockets/sockets.c:938:PHP_FUNCTION(socket_accept)
查找 grep -rn "PHP_FUNCTION(array_merge)" ./ext
返回 ./ext/standard/array.c:2266:PHP_FUNCTION(array_merge)
可以看出,PHP库函数的基本都在php-src/ext目录下,里面有具体函数库比如socket,一般的函数基本都在标准库standard. PHP源码的几个重要目录:
ext(扩展) 108M
Zend(引擎) 9.2M
sapi(cli/cgi/mod_php/fpm) 3.1M

  

php内核探索的更多相关文章

  1. php内核探索 [转]

    PHP内核探索:从SAPI接口开始 PHP内核探索:一次请求的开始与结束 PHP内核探索:一次请求生命周期 PHP内核探索:单进程SAPI生命周期 PHP内核探索:多进程/线程的SAPI生命周期 PH ...

  2. PHP内核探索之变量(7)- 不平凡的字符串

    切,一个字符串有什么好研究的. 别这么说,看过<平凡的世界>么,平凡的字符串也可以有不平凡的故事.试看: (1)       在C语言中,strlen计算字符串的时间复杂度是?PHP中呢? ...

  3. PHP内核探索之变量(6)- 后续内核探索系列大纲备忘

    年前因为工作比较饱和,现在又忙着换工作的事情,基本停止了对博文的更新.后续的博文,还是慢慢补上吧. 为了不至于过于发散,先搞个未成形的大纲,如下: PHP内核探索之变量  不平凡的字符串 PHP内核探 ...

  4. PHP内核探索之变量(5)- session的基本原理

    这次说说session. session可以说是当前互联网提到的最多的名词之一了.它的含义很宽泛,可以指任何一次完整的事务交互(会话):如发送一次HTTP请求并接受响应,执行一条SQL语句都可以看做一 ...

  5. PHP内核探索之变量(4)- 数组操作

    上一节(PHP内核探索之变量(3)- hash table),我们已经知道,数组在PHP的底层实际上是HashTable(链接法解决冲突),本文将对最常用的函数系列-数组操作的相关函数做进一步的跟踪. ...

  6. PHP内核探索之变量(3)- hash table

    在PHP中,除了zval, 另一个比较重要的数据结构非hash table莫属,例如我们最常见的数组,在底层便是hash table.除了数组,在线程安全(TSRM).GC.资源管理.Global变量 ...

  7. PHP内核探索之变量(2)-理解引用

    本文主要内容: 引论 符号表与zval 引用原理 回到最初的问题 一.引论 很久之前写了一篇关于引用的文章,当时写的寥寥草草,很多原理都没有说清楚.最近在翻阅Derick Rethans(home: ...

  8. PHP内核探索之变量(1)Zval

    作为数据的容器,我们常常需要跟变量打交道,不管这个变量是数字.数组.字符串.对象还是其他,因而可以说变量是构成语言的不可或缺的基础.本文是PHP内核探索之变量的第一篇,主要介绍zval的基本知识,包括 ...

  9. PHP内核探索:哈希碰撞攻击是什么?

    最近哈希表碰撞攻击(Hashtable collisions as DOS attack)的话题不断被提起,各种语言纷纷中招.本文结合PHP内核源码,聊一聊这种攻击的原理及实现. 哈希表碰撞攻击的基本 ...

  10. 24小时学通Linux内核--内核探索工具类

    寒假闲下来了,可以尽情的做自己喜欢的事情,专心待在实验室里燥起来了,因为大二的时候接触过Linux,只是关于内核方面确实是不好懂,所以十天的时间里还是希望能够补充一下Linux内核相关知识,接下来继续 ...

随机推荐

  1. linux c多线程编程范例

    #include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h& ...

  2. 组建你自己的Theme,组件你的Style

    Andorid-Style,组建你自己的Theme,组件你的Style 前言: 今天,尝试了一个新的Demo,也尝试深入学习,话不多说,看一下,这个Demo如何实现的自定义主题与组件Style是如何绑 ...

  3. 第三次阅读赵炯博士的《linux内核代码完全注释》:序

    这是我第三次阅读linux内核代码完全注释了,当然前两次也没有读完,第一次读到第五章,第二次第七章. 所以说,赵炯博士对我最大的帮助时介绍了intel386的结构,以及内核编程的方法. 至于真正的内核 ...

  4. windows2008 RDP修改默认端口

    PortNumber[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Teminal Sever\Wds\rdpwd\Tds\tcp] [HKE ...

  5. cocos2d-x在android中响应返回键编译报错的bug分析

    先看一段代码如何在Android中加入返回按键的响应 <span style="font-size:18px;">自己派生CCKeypadDelegate的子类,然后注 ...

  6. KMP算法——Javascript实现

    腾讯和阿里的笔试刚过去了,里面有很多题都很值得玩味的.之前Blog积累的很多东西,还要平时看的书,都有很大的帮助.这个深有体会啊! 例如,腾讯有一道算法题是吃香蕉(好邪恶的赶脚..),一次吃一根或者两 ...

  7. 可迭代的集合类型使用foreach语句

    在学习算法这本书图论那一部分的时候,接触到了几个类似for(int w:G.adj(v)),的语句,不是很理解,就去百度,发现这是一种叫做foreach的语法,在书的76页有讲到,但是之前没认真看书, ...

  8. RedHat/CentOS6.4---永久关闭iptables

    今天无意中发现一个现象,当我关闭iptables并且停止iptables服务,但是总会有一些出奇的事情发生,当我再次启动系统,查看iptables状态,iptables又自动开启,很是无奈啊!在Red ...

  9. 咏南WEB开发框架

    和咏南CS开发框架共享同一个咏南中间件.

  10. HDU 5776 sum (前缀和)

    题意:给定 n 个数,和 m,问你是不是存在连续的数和是m的倍数. 析:考虑前缀和,如果有两个前缀和取模m相等,那么就是相等的,一定要注意,如果取模为0,就是真的,不要忘记了,我当时就没记得.... ...