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. ZeroCopyLiteralByteString cannot access superclass

    问题描述 在HBase上运行MapReduce作业时,报如下异常:IllegalAccessError: class com.google.protobuf.HBaseZeroCopyByteStri ...

  2. 利用BlazeDS的AMF3数据封装与Flash 进行Socket通讯

    前几天看到了Adobe有个开源项目BlazeDS,里面提供了Java封装AMF3格式的方法.这个项目貌似主要是利用Flex来Remoting的,不过我们可以利用他来与Flash中的Socket通讯. ...

  3. Eclipse配置信息

    1.Eclipse VM arguments的保存位置: .metadata\.plugins\org.eclipse.debug.core\.launches (使用文件比较工具找出配置信息的保存位 ...

  4. QCon 2013 上海 -- 互联网金融

    互联网金融应该是最近很火爆的一个领域.由于阿里小贷和余额宝的初步成功,这一块都被视为破除传统金融领域垄断的法宝.大家可能都知道,电商平台.金融和大数据是阿里集团未来的三个重要方面.而关于金融,马云最经 ...

  5. Windows Azure Platform 系列文章目录

    Windows Azure Platform (一) 云计算的出现 Windows Azure Platform (二) 云计算的分类和服务层次 Windows Azure Platform (三) ...

  6. Message Forwarding

    [Preprocess] 在使用forwarding机制前,会先经历2个步骤,只有当这2个步骤均失败的情况下,才会激活forwarding. 1.+(BOOL)resolveInstanceMetho ...

  7. POJ 3177 Redundant Paths POJ 3352 Road Construction

    这两题是一样的,代码完全一样. 就是给了一个连通图,问加多少条边可以变成边双连通. 去掉桥,其余的连通分支就是边双连通分支了.一个有桥的连通图要变成边双连通图的话,把双连通子图收缩为一个点,形成一颗树 ...

  8. linux之间连接—使用SSH

    菜鸟学linux笔记.本机是linux,需要远程连接linux,使用SSH (1)在终端,输入命令:ssh root@110.110.100.100 root为用户名,110.110.100.100为 ...

  9. Linux /proc 的意义

    /proc 是个虚拟文件系统.也就是.重新引导后修改会被重新初始化     提供了进程信息.内存资源.硬件设备.内核内存等信息     比如:     网卡:/proc/sys/vm/ipv4/ip_ ...

  10. android ListView中的Item有Button时候点击异常处理

    1.当ListView中有Button的时候往往会遇到很多问题,比较常见的一个问题是: 假设:在ListView中有N个Item当点击其中某个Item中的Button的时候,需要改变当前Button的 ...