### 1.zval定义
```
struct _zval_struct {
zend_value value;
union u1;
union u2;
}
```
### 1.zend_value定义(8字节)
```
typeof union_zend_value {
zend_long lval;
double dval;
zend_refcounted *counted;
zend_string *str;
zend_array *arr;
zend_object *obj;
zend_resource *res;
zend_reference *ref;
zend_ast_ref *ast; //语法树
zval *zv
void *ptr;
zend_class_entry *ce //类
zend_function *func //函数
等等
} zend_value;
```
### 3.u1(4字节)
```
union {
struct {
ZEND_ENDIAN_LOHI_4 (
zend_uchar type;
zend_uchar type_flags;
zend_uchar const_flags;
zend_uchar reserved;
)
} v;
uint32_t type_info;
} u1;
```
### 3.u2(4字节)
```
union {
union32_t next;
union32_t cache_slog;
union32_t lineno;
union32_t num_args;
union32_t fe_pos;
union32_t fe_iter_idx;
union32_t access_flags;
union32_t property_guard;
} u2;
```
### 结构体:
![](https://img.kancloud.cn/46/16/46165d66846dfcd0ff567c2f28803f2a_534x214.png)
## 查看源码
➜ vim /opt/php-7.4.9/Zend/zend_types.h
![](https://img.kancloud.cn/e1/aa/e1aafc014acbc0f4f4656290ea378cd0_1220x652.png)
![](https://img.kancloud.cn/df/8e/df8ee0b8867708fbf75934e6403b23d5_1368x950.png)
u1中 type定义的类型有这些
![](https://img.kancloud.cn/e2/d7/e2d74ad955b89a086881eb7062c79ca8_964x442.png)
其他类型
![](https://img.kancloud.cn/b8/45/b8456922859e7acb37ec38874ee005f0_1144x522.png)
### 实战
```
gdb php
1.打断点echo处
b ZEND_ECHO_SPEC_CV_HANDLER
2.运行
r test_bianliang.php
3.进入gdb
(gdb) n
36911z = EX_VAR(opline->op1.var);
(gdb) n
36913if (Z_TYPE_P(z) == IS_STRING) {
(gdb) p z
$1 = (zval *) 0x7ffff6214070
(gdb) p *z
$2 = {value = {lval = 2, dval = 9.8813129168249309e-324, counted = 0x2, str = 0x2, arr = 0x2,
obj = 0x2, res = 0x2, ref = 0x2, ast = 0x2, zv = 0x2, ptr = 0x2, ce = 0x2, func = 0x2, ww = {
w1 = 2, w2 = 0}}, u1 = {v = {type = 4 '\004', type_flags = 0 '\000', u = {extra = 0}},
type_info = 4}, u2 = {next = 0, cache_slot = 0, opline_num = 0, lineno = 0, num_args = 0,
fe_pos = 0, fe_iter_idx = 0, access_flags = 0, property_guard = 0, constant_flags = 0, extra = 0}}
(gdb)
----解释_start----
type = 4 表示 IS_LONG 就是整形,整形取的是zend_value里面的 value = {lval = 2,
----解释_end----
$2 = {
value =
{
lval = 2,
dval = 9.8813129168249309e-324,
counted = 0x2,
str = 0x2,
arr = 0x2,
obj = 0x2,
res = 0x2,
ref = 0x2,
ast = 0x2,
zv = 0x2,
ptr = 0x2,
ce = 0x2,
func = 0x2,
ww = {
w1 = 2,
w2 = 0
}
},
u1 = {
v = {
type = 4 '\004',
type_flags = 0 '\000',
u = {
extra = 0
}
},
type_info = 4
},
u2 = {
next = 0,
cache_slot = 0,
opline_num = 0,
lineno = 0,
num_args = 0,
fe_pos = 0,
fe_iter_idx = 0,
access_flags = 0,
property_guard = 0,
constant_flags = 0,
extra = 0
}
}
(gdb) c
Continuing.
(gdb) n
36913if (Z_TYPE_P(z) == IS_STRING) {
(gdb) p z
$1 = (zval *) 0x7ffff6214080
(gdb) p z*
A syntax error in expression, near `'.
(gdb) p *z
$2 = {value = {lval = 4607632778762754458, dval = 1.1000000000000001, counted = 0x3ff199999999999a,
str = 0x3ff199999999999a, arr = 0x3ff199999999999a, obj = 0x3ff199999999999a,
res = 0x3ff199999999999a, ref = 0x3ff199999999999a, ast = 0x3ff199999999999a,
zv = 0x3ff199999999999a, ptr = 0x3ff199999999999a, ce = 0x3ff199999999999a,
func = 0x3ff199999999999a, ww = {w1 = 2576980378, w2 = 1072798105}}, u1 = {v = {type = 5 '\005',
type_flags = 0 '\000', u = {extra = 0}}, type_info = 5}, u2 = {next = 0, cache_slot = 0,
opline_num = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, access_flags = 0,
property_guard = 0, constant_flags = 0, extra = 0}}
----解释_start----
type = 5 表示 DOUBLE,因为有精度问题 ,所以展示 1.1000000000000001
----解释_end----
(gdb) c
(gdb) n
36911z = EX_VAR(opline->op1.var);
(gdb) n
36913if (Z_TYPE_P(z) == IS_STRING) {
(gdb) p *z
$3 = {value = {lval = 140737323064608,
dval = 6.9533476413883715e-310,
counted = 0x7ffff625dd20, str = 0x7ffff625dd20,
arr = 0x7ffff625dd20, obj = 0x7ffff625dd20,
res = 0x7ffff625dd20, ref = 0x7ffff625dd20,
ast = 0x7ffff625dd20, zv = 0x7ffff625dd20,
ptr = 0x7ffff625dd20, ce = 0x7ffff625dd20,
func = 0x7ffff625dd20, ww = {w1 = 4129676576,
w2 = 32767}}, u1 = {v = {type = 6 '\006',
type_flags = 0 '\000', u = {extra = 0}},
type_info = 6}, u2 = {next = 0, cache_slot = 0,
opline_num = 0, lineno = 0, num_args = 0, fe_pos = 0,
fe_iter_idx = 0, access_flags = 0,
(gdb) p $3.value.str
$4 = (zend_string *) 0x7ffff625dd20
(gdb) p *$3.value.str
$5 = {gc = {refcount = 1, u = {type_info = 70}},
h = 9473279104216990709, len = 9, val = "s"}
----解释_start----
因为字符串的长度是 sunmaomao 。所以len=9
----解释_end----
```
![](https://img.kancloud.cn/2d/8f/2d8f4aeb804c710c05b626e3acc50cf3_1670x192.png)
![](https://img.kancloud.cn/82/ef/82ef6c7f16d21da763a7656876693ca8_604x432.png)
### php运行什么周期
1.php_module_startup ->模块初始化
2.php_request_startup->请求初始化
3.php_execute_script->脚本执行阶段
4.php_request_shutdown-> 请求关闭阶段
5.php_module_shutdown ->模块关闭阶段
```
cd /opt/testphp
gdb php
b main
r test_hello.php
b php_module_startup
b php_request_startup
b php_execute_script
b php_request_shutdown
b php_module_shutdown
c
bt
```
![](https://img.kancloud.cn/35/e8/35e846a6a64e21490040950f4d496bbc_1232x982.png)
![](https://img.kancloud.cn/78/6e/786ea0d1b76896a42142c4b1e81b43d5_1304x856.png)
### PHP-FPM测试
php-fpm的www.conf设置 静态并且 子进程是1
1.kill 主进程 (master) 还能服务吗 ->不能服务
2.kill -9 主进程(master) 还能服务吗 ->可以,他只是管理子进程的
3.kill 子进程 (worker) 还能服务吗 ->可以,主进程会新增一个子进程
4.kill -9 worker) 还能服务吗 ->可以
![](https://img.kancloud.cn/da/21/da21467931e8c19f60c6876083877c96_1016x712.png)
### TCPDUMP抓包
`tcpdump -i eth0 port 9000 -XX -S`
![](https://img.kancloud.cn/29/f8/29f83886e3719dcf6fa15a6a3743796a_2192x942.png)
###PHP 编译
![](https://img.kancloud.cn/c0/5f/c05fcd073149044b4b28d8dca6bb661f_1062x502.png)
![](https://img.kancloud.cn/3c/95/3c9509906bdcf36bb818a670b9e20580_1006x532.png)