SlideShare ist ein Scribd-Unternehmen logo
1 von 43
Downloaden Sie, um offline zu lesen
Internal PHP and gdb php core
alpha.1986@gmail.com
Agenda
• Overview
• PHP lifecycle
• Zend Engine 2 & PHP Opcodes
• PHP 变量
• PHP 函数
• PHP OO
• Some Details
• PHP extensions
• gdb php core
Overview
Overview
• Php 5.2.x
– Zend Engine 2.0
• OO的改进
Overview – 代码结构
• main
– php的核心文件以及基础设施
• Zend
– Zend engine2
– 词法语法分析,虚拟机,所有与”php”相关的
• ext
– 扩展目录
• sapi
– 服务器抽象层(mod_php,fastcgi,etc)
• TSRM
– 线程安全相关
PHP lifecycle - CLI
PHP lifecycle – Apache Multiprocess
Individual process life cycle
PHP lifecycle – Apache Multiprocess
Multiprocess life cycles
PHP lifecycle – 扩展
• PHP_MINIT_FUNCTION(mysqli);
• PHP_MSHUTDOWN_FUNCTION(mysqli);
• PHP_RINIT_FUNCTION(mysqli);
• PHP_RSHUTDOWN_FUNCTION(mysqli);
PHP lifecycle – execute PHP
• Lexical Analysis
• Syntax Analysis
• Opcodes Generation
• Opcodes Execution
PHP lifecycle – PHP Execution
*.php
lex
Exprs
yacc
opcodes
Zend
vm
zend_language_scanner.l
zend_language_parser.y
eAccelerator(eacc)
eaccelerator.c,
PHP_MINIT_FUNCTION(eaccele
rator)
PHP lifecycle – tokens
zend_language_scanner.l 中有所有token的定义,php的token_get_all函数可以获得
一段php代码的token
Opcodes
zend_op_array
Zend Engine 2 & PHP Opcodes
php_execute_scrip
t()
zend_execute_scripts()
zend_execute()
user call
(function/method)
包括定义在php中的函数和扩展里的函数
include/require
zend_compile_file()
函数指针
Zend engine 整体流程
Zend Engine 2 - execute_scripts
• PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
(main/main.c)
• ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int
file_count, ...) (Zend/zend.c)
• php_execute_script把auto_prepend_file,
primary_file,auto_prepend_file这三个文件
传给zend_execute_scripts
Zend Engine 2 - zend_compile_file
• Zend/zend.c zend_startup
• 默认指向compile_file() in zend_language_scanner.c
• ZEND_API zend_op_array *compile_file(zend_file_handle
*file_handle, int type TSRMLS_DC)
• Lexical Analysis -> Syntax Analysis -> Opcodes Generation
PHP Opcodes
<?php
echo "hello world!";
通过vld扩展可以查看opcode,space@bb-space-test000
/home/space/php5/bin/php -dvld.active=1 test3.php
PHP Opcodes
<?php
function testHello(){
return "hello world";
}
echo testHello();
PHP Opcodes
struct _zend_op {
opcode_handler_t handler; //每一个opcode对应的回调
znode result;
znode op1;
znode op2;
ulong extended_value;
uint lineno;
zend_uchar opcode; // opcode值
};
typedef int (*opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);
typedef unsigned char zend_uchar;
//zend_compile.h( _zend_op_array 也在这里)
PHP Opcodes
• Opcodes由zend_execute来执行
• 默认情况,zend_execute指向zend_vm_execute.h
的
ZEND_API void execute(zend_op_array *op_array
TSRMLS_DC)
• 每个opcode的回调都存在全局变量zend_opcode_handlers
中,初始化在zend_init_opcodes_handlers()
• 回调命名规则
ZEND_[opcode]_SPEC_(变量类型1)_(变量类型2)_HANDLER
PHP 变量
• 弱类型
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;
//zend.h
typedef struct _zval_struct zval;
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount;
zend_uchar type; /* active type */
zend_uchar is_ref;
};
PHP 变量 - type
/* data types */ // zval.type
/* All data types <= IS_BOOL have their constructor/destructors
skipped */
#define IS_NULL 0
#define IS_LONG 1
#define IS_DOUBLE 2
#define IS_BOOL 3
#define IS_ARRAY 4
#define IS_OBJECT 5
#define IS_STRING 6
#define IS_RESOURCE 7
#define IS_CONSTANT 8
#define IS_CONSTANT_ARRAY 9
PHP 变量 - HashTable
• 整个zend engine最核心的数据结构
• 不仅仅是php中的array,ze中大量采用
HashTable来实现自己的逻辑,比如OO的逻辑,
全局大变量等等
• zend_hash.h
PHP 函数
<?php
fcrypt_hstr_2id("space","aaaa");
strstr("abcde","abc");
echo "done";
PHP中的user_function和扩展中的函数都是DO_FCALL指令,echo是指令不是函数
PHP 函数
• DO_FCALL最终调到
static int
zend_do_fcall_common_helper_SPEC(ZEND_OPCOD
E_HANDLER_ARGS)
// zend_vm_execute.h
zend_do_fcall_common_helper_SPEC
PHP 函数
• 两种类型函数
– User function(写在php代码中的函数)
– Internal function(扩展中的函数)
• Php代码的函数栈会在zend vm中也体现出
来!
– 就是zend_do_fcall_common_helper_SPEC形成的
栈(还包括execute,zend_execute_internal等)
• abc
PHP 函数 – 函数类型
#define ZEND_INTERNAL_FUNCTION 1
#define ZEND_USER_FUNCTION 2
#define ZEND_OVERLOADED_FUNCTION 3
#define ZEND_EVAL_CODE 4
#define ZEND_OVERLOADED_FUNCTION_TEMPORARY
typedef union _zend_function {
zend_uchar type; /* MUST be the first element of this struct! */
struct {
zend_uchar type; /* never used */
char *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
union _zend_function *prototype;
zend_uint num_args;
zend_uint required_num_args;
zend_arg_info *arg_info;
zend_bool pass_rest_by_reference;
unsigned char return_reference;
} common;
zend_op_array op_array;
zend_internal_function internal_function;
} zend_function;
PHP OO
struct _zend_class_entry {
char type;
char *name;
zend_uint name_length;
struct _*parent;
int refcozend_class_entry unt;
HashTable function_table;
HashTable default_properties;
HashTable properties_info;
HashTable default_static_members;
HashTable *static_members;
HashTable constants_table;
struct _zend_function_entry *builtin_functions;
union _zend_function *constructor;
union _zend_function *destructor;
union _zend_function *clone;
union _zend_function *__get;
union _zend_function *serialize_func;
union _zend_function *unserialize_func;
……..
Some Details
• 大量的宏
– # define EG(v) (executor_globals.v)
//Zend/zend_globals_macros.h
– #define EX(element) execute_data->element
比较重要的全局变量
• ZEND_API zend_compiler_globals
compiler_globals;
• ZEND_API zend_executor_globals
executor_globals;
• 尤其对于executor_globals会有大量的运行时
数据
PHP extensions(学习hack php的一些思路)
• eAccelerator
• Xdebug
• Xphrof
PHP extensions - eAccelerator
• PHP_MINIT_FUNCTION(eaccelerator) 中
zend_compile_file = eaccelerator_compile_file;
• eaccelerator_compile_file会首先从cache中读
opcode,没有cache才会重新生成,cache
• 来实现opcode cache
PHP extensions - xdebug
• 函数调用的性能分析
// PHP_MINIT_FUNCTION
old_compile_file = zend_compile_file;
zend_compile_file = xdebug_compile_file;
xdebug_old_execute = zend_execute;
zend_execute = xdebug_execute;
xdebug_orig_header_handler = sapi_module.header_handler;
sapi_module.header_handler = xdebug_header_handler;
xdebug_execute做完一堆
事情后,再调回
xdebug_old_execute
PHP extensions - xdebug
• 代码覆盖率分析
// PHP_MINIT_FUNCTION
if (XG(coverage_enable)) {
XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMP);
XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMPZ);
XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMPZ_EX);
XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMPNZ);
#define XDEBUG_SET_OPCODE_OVERRIDE_COMMON(oc) 
zend_set_user_opcode_handler(oc, xdebug_common_override_handler);
PHP extensions - Xphrof
• PHP_FUNCTION(xhprof_enable) 中进行
_zend_compile_file = zend_compile_file;
zend_compile_file = hp_compile_file;
/* Replace zend_execute with our proxy */
_zend_execute = zend_execute;
zend_execute = hp_execute;
gdb php core
类似于下面这种,需要了解php的逻辑来排查问题的
gdb php core
• source ~/php-5.2.10/.gdbinit 初始化一些gdb
命令(方便查询hashtable)
• 如果获取当前执行在php的那个函数?
gdb php core – 在哪个类?
gdb php core – 获取php中的全局变量
• $_SERVER,$_GET,$_POST 等这些php代码中
的大变量如何获取?
• executor_globals
• executor_globals->symbol_table 全局的变量
在这个符号表里
这次没有涉及到的
• PHP SAPI架构
• PHP HashTable细节
• PHP内存管理
• PHP ZTS & TSRM等线程安全机制
• OO的更多细节以及如何编写OO扩展
• 变量的作用域
• Zend vm更深入的分析
• 等等
• 这些内容也期待大家共同参与
参考资料
• Php.net
• Extending and Embedding PHP
• http://www.php-internal.com/
• http://www.laruence.com/
Thank you!

Weitere ähnliche Inhalte

Was ist angesagt?

OpenEJB - 另一個選擇
OpenEJB - 另一個選擇OpenEJB - 另一個選擇
OpenEJB - 另一個選擇Justin Lin
 
Perl在nginx里的应用
Perl在nginx里的应用Perl在nginx里的应用
Perl在nginx里的应用琛琳 饶
 
Composer 套件管理
Composer 套件管理Composer 套件管理
Composer 套件管理Shengyou Fan
 
advanced introduction to codeigniter
advanced introduction to codeigniteradvanced introduction to codeigniter
advanced introduction to codeigniterBo-Yi Wu
 
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘Liu Allen
 
深入淺出 Web 容器 - Tomcat 原始碼分析
深入淺出 Web 容器  - Tomcat 原始碼分析深入淺出 Web 容器  - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析Justin Lin
 
Python 于 webgame 的应用
Python 于 webgame 的应用Python 于 webgame 的应用
Python 于 webgame 的应用勇浩 赖
 
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & WindowsChu-Siang Lai
 
學好 node.js 不可不知的事
學好 node.js 不可不知的事學好 node.js 不可不知的事
學好 node.js 不可不知的事Ben Lue
 
JavaScript 80+ Programming and Optimization Skills
JavaScript 80+ Programming and Optimization SkillsJavaScript 80+ Programming and Optimization Skills
JavaScript 80+ Programming and Optimization SkillsHo Kim
 
啟動 Laravel 與環境設定
啟動 Laravel 與環境設定啟動 Laravel 與環境設定
啟動 Laravel 與環境設定Shengyou Fan
 
Symfony簡介
Symfony簡介Symfony簡介
Symfony簡介Ricky Su
 
Automate with Ansible basic (3/e)
Automate with Ansible basic (3/e)Automate with Ansible basic (3/e)
Automate with Ansible basic (3/e)Chu-Siang Lai
 
Introduction to MVC of CodeIgniter 2.1.x
Introduction to MVC of CodeIgniter 2.1.xIntroduction to MVC of CodeIgniter 2.1.x
Introduction to MVC of CodeIgniter 2.1.xBo-Yi Wu
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎Shengyou Fan
 
Javascript autoload
Javascript autoloadJavascript autoload
Javascript autoloadjay li
 
深入PHP内核之路
深入PHP内核之路深入PHP内核之路
深入PHP内核之路Gump Law
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎Shengyou Fan
 
現代 IT 人一定要知道的 Ansible 自動化組態技巧
現代 IT 人一定要知道的 Ansible 自動化組態技巧現代 IT 人一定要知道的 Ansible 自動化組態技巧
現代 IT 人一定要知道的 Ansible 自動化組態技巧Chu-Siang Lai
 

Was ist angesagt? (20)

OpenEJB - 另一個選擇
OpenEJB - 另一個選擇OpenEJB - 另一個選擇
OpenEJB - 另一個選擇
 
Perl在nginx里的应用
Perl在nginx里的应用Perl在nginx里的应用
Perl在nginx里的应用
 
Composer 套件管理
Composer 套件管理Composer 套件管理
Composer 套件管理
 
Php
PhpPhp
Php
 
advanced introduction to codeigniter
advanced introduction to codeigniteradvanced introduction to codeigniter
advanced introduction to codeigniter
 
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
 
深入淺出 Web 容器 - Tomcat 原始碼分析
深入淺出 Web 容器  - Tomcat 原始碼分析深入淺出 Web 容器  - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析
 
Python 于 webgame 的应用
Python 于 webgame 的应用Python 于 webgame 的应用
Python 于 webgame 的应用
 
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
現代 IT 人一定要知道的 Ansible 自動化組態技巧 Ⅱ - Roles & Windows
 
學好 node.js 不可不知的事
學好 node.js 不可不知的事學好 node.js 不可不知的事
學好 node.js 不可不知的事
 
JavaScript 80+ Programming and Optimization Skills
JavaScript 80+ Programming and Optimization SkillsJavaScript 80+ Programming and Optimization Skills
JavaScript 80+ Programming and Optimization Skills
 
啟動 Laravel 與環境設定
啟動 Laravel 與環境設定啟動 Laravel 與環境設定
啟動 Laravel 與環境設定
 
Symfony簡介
Symfony簡介Symfony簡介
Symfony簡介
 
Automate with Ansible basic (3/e)
Automate with Ansible basic (3/e)Automate with Ansible basic (3/e)
Automate with Ansible basic (3/e)
 
Introduction to MVC of CodeIgniter 2.1.x
Introduction to MVC of CodeIgniter 2.1.xIntroduction to MVC of CodeIgniter 2.1.x
Introduction to MVC of CodeIgniter 2.1.x
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎
 
Javascript autoload
Javascript autoloadJavascript autoload
Javascript autoload
 
深入PHP内核之路
深入PHP内核之路深入PHP内核之路
深入PHP内核之路
 
View 與 Blade 樣板引擎
View 與 Blade 樣板引擎View 與 Blade 樣板引擎
View 與 Blade 樣板引擎
 
現代 IT 人一定要知道的 Ansible 自動化組態技巧
現代 IT 人一定要知道的 Ansible 自動化組態技巧現代 IT 人一定要知道的 Ansible 自動化組態技巧
現代 IT 人一定要知道的 Ansible 自動化組態技巧
 

Ähnlich wie Internal php and gdb php core

Linux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeLinux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeAngel Boy
 
PHP更有效率的除錯 - XDebug
PHP更有效率的除錯 - XDebugPHP更有效率的除錯 - XDebug
PHP更有效率的除錯 - XDebugTaien Wang
 
Web development with zend framework
Web development with zend frameworkWeb development with zend framework
Web development with zend frameworkthinkinlamp
 
高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术wensheng wei
 
大话Php之性能
大话Php之性能大话Php之性能
大话Php之性能liqiang xu
 
Binary exploitation - AIS3
Binary exploitation - AIS3Binary exploitation - AIS3
Binary exploitation - AIS3Angel Boy
 
Php extension开发
Php extension开发Php extension开发
Php extension开发thinkinlamp
 
推薦系統實作
推薦系統實作推薦系統實作
推薦系統實作FEG
 
Php设计模式介绍
Php设计模式介绍Php设计模式介绍
Php设计模式介绍cyf5513
 
Web coding principle
Web coding principleWeb coding principle
Web coding principleZongYing Lyu
 
Modern php ch8 ch9 guide 導讀
Modern php ch8 ch9 guide 導讀Modern php ch8 ch9 guide 導讀
Modern php ch8 ch9 guide 導讀Chen Cheng-Wei
 
Wamp环境下安装 wordpress
Wamp环境下安装 wordpressWamp环境下安装 wordpress
Wamp环境下安装 wordpressstrugglesmen
 
KISSY Editor Design 2
KISSY Editor Design 2KISSY Editor Design 2
KISSY Editor Design 2yiming he
 
MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程Lixun Peng
 
OpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part IOpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part IHung-yu Lin
 
模块一-Go语言特性.pdf
模块一-Go语言特性.pdf模块一-Go语言特性.pdf
模块一-Go语言特性.pdfczzz1
 
PHP and Zend Internal I - 体系结构及生命周期
PHP and Zend Internal I - 体系结构及生命周期PHP and Zend Internal I - 体系结构及生命周期
PHP and Zend Internal I - 体系结构及生命周期ericzhangcn
 
4. Go 工程化实践-0124-v2.pdf
4. Go 工程化实践-0124-v2.pdf4. Go 工程化实践-0124-v2.pdf
4. Go 工程化实践-0124-v2.pdfssuserd6c7621
 
開發環境建置
開發環境建置開發環境建置
開發環境建置Shengyou Fan
 

Ähnlich wie Internal php and gdb php core (20)

Linux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeLinux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledge
 
PHP更有效率的除錯 - XDebug
PHP更有效率的除錯 - XDebugPHP更有效率的除錯 - XDebug
PHP更有效率的除錯 - XDebug
 
Web development with zend framework
Web development with zend frameworkWeb development with zend framework
Web development with zend framework
 
高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术
 
大话Php之性能
大话Php之性能大话Php之性能
大话Php之性能
 
Binary exploitation - AIS3
Binary exploitation - AIS3Binary exploitation - AIS3
Binary exploitation - AIS3
 
Php extension开发
Php extension开发Php extension开发
Php extension开发
 
推薦系統實作
推薦系統實作推薦系統實作
推薦系統實作
 
Php设计模式介绍
Php设计模式介绍Php设计模式介绍
Php设计模式介绍
 
Web coding principle
Web coding principleWeb coding principle
Web coding principle
 
Node分享 展烨
Node分享 展烨Node分享 展烨
Node分享 展烨
 
Modern php ch8 ch9 guide 導讀
Modern php ch8 ch9 guide 導讀Modern php ch8 ch9 guide 導讀
Modern php ch8 ch9 guide 導讀
 
Wamp环境下安装 wordpress
Wamp环境下安装 wordpressWamp环境下安装 wordpress
Wamp环境下安装 wordpress
 
KISSY Editor Design 2
KISSY Editor Design 2KISSY Editor Design 2
KISSY Editor Design 2
 
MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程MySQL源码分析.01.代码结构与基本流程
MySQL源码分析.01.代码结构与基本流程
 
OpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part IOpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part I
 
模块一-Go语言特性.pdf
模块一-Go语言特性.pdf模块一-Go语言特性.pdf
模块一-Go语言特性.pdf
 
PHP and Zend Internal I - 体系结构及生命周期
PHP and Zend Internal I - 体系结构及生命周期PHP and Zend Internal I - 体系结构及生命周期
PHP and Zend Internal I - 体系结构及生命周期
 
4. Go 工程化实践-0124-v2.pdf
4. Go 工程化实践-0124-v2.pdf4. Go 工程化实践-0124-v2.pdf
4. Go 工程化实践-0124-v2.pdf
 
開發環境建置
開發環境建置開發環境建置
開發環境建置
 

Internal php and gdb php core

  • 1. Internal PHP and gdb php core alpha.1986@gmail.com
  • 2. Agenda • Overview • PHP lifecycle • Zend Engine 2 & PHP Opcodes • PHP 变量 • PHP 函数 • PHP OO • Some Details • PHP extensions • gdb php core
  • 4. Overview • Php 5.2.x – Zend Engine 2.0 • OO的改进
  • 5. Overview – 代码结构 • main – php的核心文件以及基础设施 • Zend – Zend engine2 – 词法语法分析,虚拟机,所有与”php”相关的 • ext – 扩展目录 • sapi – 服务器抽象层(mod_php,fastcgi,etc) • TSRM – 线程安全相关
  • 7. PHP lifecycle – Apache Multiprocess Individual process life cycle
  • 8. PHP lifecycle – Apache Multiprocess Multiprocess life cycles
  • 9. PHP lifecycle – 扩展 • PHP_MINIT_FUNCTION(mysqli); • PHP_MSHUTDOWN_FUNCTION(mysqli); • PHP_RINIT_FUNCTION(mysqli); • PHP_RSHUTDOWN_FUNCTION(mysqli);
  • 10. PHP lifecycle – execute PHP • Lexical Analysis • Syntax Analysis • Opcodes Generation • Opcodes Execution
  • 11. PHP lifecycle – PHP Execution *.php lex Exprs yacc opcodes Zend vm zend_language_scanner.l zend_language_parser.y eAccelerator(eacc) eaccelerator.c, PHP_MINIT_FUNCTION(eaccele rator)
  • 12. PHP lifecycle – tokens zend_language_scanner.l 中有所有token的定义,php的token_get_all函数可以获得 一段php代码的token
  • 13. Opcodes zend_op_array Zend Engine 2 & PHP Opcodes php_execute_scrip t() zend_execute_scripts() zend_execute() user call (function/method) 包括定义在php中的函数和扩展里的函数 include/require zend_compile_file() 函数指针 Zend engine 整体流程
  • 14. Zend Engine 2 - execute_scripts • PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC) (main/main.c) • ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) (Zend/zend.c) • php_execute_script把auto_prepend_file, primary_file,auto_prepend_file这三个文件 传给zend_execute_scripts
  • 15. Zend Engine 2 - zend_compile_file • Zend/zend.c zend_startup • 默认指向compile_file() in zend_language_scanner.c • ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) • Lexical Analysis -> Syntax Analysis -> Opcodes Generation
  • 16. PHP Opcodes <?php echo "hello world!"; 通过vld扩展可以查看opcode,space@bb-space-test000 /home/space/php5/bin/php -dvld.active=1 test3.php
  • 17. PHP Opcodes <?php function testHello(){ return "hello world"; } echo testHello();
  • 18. PHP Opcodes struct _zend_op { opcode_handler_t handler; //每一个opcode对应的回调 znode result; znode op1; znode op2; ulong extended_value; uint lineno; zend_uchar opcode; // opcode值 }; typedef int (*opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS); typedef unsigned char zend_uchar; //zend_compile.h( _zend_op_array 也在这里)
  • 19. PHP Opcodes • Opcodes由zend_execute来执行 • 默认情况,zend_execute指向zend_vm_execute.h 的 ZEND_API void execute(zend_op_array *op_array TSRMLS_DC) • 每个opcode的回调都存在全局变量zend_opcode_handlers 中,初始化在zend_init_opcodes_handlers() • 回调命名规则 ZEND_[opcode]_SPEC_(变量类型1)_(变量类型2)_HANDLER
  • 20. PHP 变量 • 弱类型 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; //zend.h typedef struct _zval_struct zval; struct _zval_struct { /* Variable information */ zvalue_value value; /* value */ zend_uint refcount; zend_uchar type; /* active type */ zend_uchar is_ref; };
  • 21. PHP 变量 - type /* data types */ // zval.type /* All data types <= IS_BOOL have their constructor/destructors skipped */ #define IS_NULL 0 #define IS_LONG 1 #define IS_DOUBLE 2 #define IS_BOOL 3 #define IS_ARRAY 4 #define IS_OBJECT 5 #define IS_STRING 6 #define IS_RESOURCE 7 #define IS_CONSTANT 8 #define IS_CONSTANT_ARRAY 9
  • 22. PHP 变量 - HashTable • 整个zend engine最核心的数据结构 • 不仅仅是php中的array,ze中大量采用 HashTable来实现自己的逻辑,比如OO的逻辑, 全局大变量等等 • zend_hash.h
  • 24. PHP 函数 • DO_FCALL最终调到 static int zend_do_fcall_common_helper_SPEC(ZEND_OPCOD E_HANDLER_ARGS) // zend_vm_execute.h
  • 26. PHP 函数 • 两种类型函数 – User function(写在php代码中的函数) – Internal function(扩展中的函数) • Php代码的函数栈会在zend vm中也体现出 来! – 就是zend_do_fcall_common_helper_SPEC形成的 栈(还包括execute,zend_execute_internal等) • abc
  • 27. PHP 函数 – 函数类型 #define ZEND_INTERNAL_FUNCTION 1 #define ZEND_USER_FUNCTION 2 #define ZEND_OVERLOADED_FUNCTION 3 #define ZEND_EVAL_CODE 4 #define ZEND_OVERLOADED_FUNCTION_TEMPORARY typedef union _zend_function { zend_uchar type; /* MUST be the first element of this struct! */ struct { zend_uchar type; /* never used */ char *function_name; zend_class_entry *scope; zend_uint fn_flags; union _zend_function *prototype; zend_uint num_args; zend_uint required_num_args; zend_arg_info *arg_info; zend_bool pass_rest_by_reference; unsigned char return_reference; } common; zend_op_array op_array; zend_internal_function internal_function; } zend_function;
  • 28. PHP OO struct _zend_class_entry { char type; char *name; zend_uint name_length; struct _*parent; int refcozend_class_entry unt; HashTable function_table; HashTable default_properties; HashTable properties_info; HashTable default_static_members; HashTable *static_members; HashTable constants_table; struct _zend_function_entry *builtin_functions; union _zend_function *constructor; union _zend_function *destructor; union _zend_function *clone; union _zend_function *__get; union _zend_function *serialize_func; union _zend_function *unserialize_func; ……..
  • 29. Some Details • 大量的宏 – # define EG(v) (executor_globals.v) //Zend/zend_globals_macros.h – #define EX(element) execute_data->element
  • 30. 比较重要的全局变量 • ZEND_API zend_compiler_globals compiler_globals; • ZEND_API zend_executor_globals executor_globals; • 尤其对于executor_globals会有大量的运行时 数据
  • 31. PHP extensions(学习hack php的一些思路) • eAccelerator • Xdebug • Xphrof
  • 32. PHP extensions - eAccelerator • PHP_MINIT_FUNCTION(eaccelerator) 中 zend_compile_file = eaccelerator_compile_file; • eaccelerator_compile_file会首先从cache中读 opcode,没有cache才会重新生成,cache • 来实现opcode cache
  • 33. PHP extensions - xdebug • 函数调用的性能分析 // PHP_MINIT_FUNCTION old_compile_file = zend_compile_file; zend_compile_file = xdebug_compile_file; xdebug_old_execute = zend_execute; zend_execute = xdebug_execute; xdebug_orig_header_handler = sapi_module.header_handler; sapi_module.header_handler = xdebug_header_handler; xdebug_execute做完一堆 事情后,再调回 xdebug_old_execute
  • 34. PHP extensions - xdebug • 代码覆盖率分析 // PHP_MINIT_FUNCTION if (XG(coverage_enable)) { XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMP); XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMPZ); XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMPZ_EX); XDEBUG_SET_OPCODE_OVERRIDE_COMMON(ZEND_JMPNZ); #define XDEBUG_SET_OPCODE_OVERRIDE_COMMON(oc) zend_set_user_opcode_handler(oc, xdebug_common_override_handler);
  • 35. PHP extensions - Xphrof • PHP_FUNCTION(xhprof_enable) 中进行 _zend_compile_file = zend_compile_file; zend_compile_file = hp_compile_file; /* Replace zend_execute with our proxy */ _zend_execute = zend_execute; zend_execute = hp_execute;
  • 37. gdb php core • source ~/php-5.2.10/.gdbinit 初始化一些gdb 命令(方便查询hashtable) • 如果获取当前执行在php的那个函数?
  • 38. gdb php core – 在哪个类?
  • 39. gdb php core – 获取php中的全局变量 • $_SERVER,$_GET,$_POST 等这些php代码中 的大变量如何获取? • executor_globals • executor_globals->symbol_table 全局的变量 在这个符号表里
  • 40.
  • 41. 这次没有涉及到的 • PHP SAPI架构 • PHP HashTable细节 • PHP内存管理 • PHP ZTS & TSRM等线程安全机制 • OO的更多细节以及如何编写OO扩展 • 变量的作用域 • Zend vm更深入的分析 • 等等 • 这些内容也期待大家共同参与
  • 42. 参考资料 • Php.net • Extending and Embedding PHP • http://www.php-internal.com/ • http://www.laruence.com/