SlideShare a Scribd company logo
ianzhang
What is Extension standard extension 自定义 extension
What is Extension apc, mysqli 等都是 extension 默认放在 /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613 中 在 php.ini 中开启需要的 extension
Extension 能做什么 和不同业务交互,接口是 C/C++ 接口,我们需要 extension 从 php 和这些接口交 互,协议接口 使用 extension 和共享内存交互,和高性能 c 程序完成高性能工作  -  数据库异步写操作 利用 c 的运算速度,完成高性能算法在 php 中的实现  将之前必须在 c 的环境下的工作,转移到 php 中 – 高性能 server 在 php 中的开发
今天的目标 Hello World 一个简单的加法运算函数
开发环境 Linux 系统 autoconfig php 源码 安装好的 php 环境 That‘s All ! Easy
PHP 程序生命周期
Apache PHP 子进程
Begin 所有 extension 的编译环境都放在源代码的 Ext 子目录下  使用自动构建系统 ./ext_skel --extname = my_module  创建了名为 my_module 的文件夹
config.m4 用于 Autoconfig,  用 m4 文件来处理宏生成需要的 configure 文件 config.m4  文件负责在配置时解析 configure  的命令行选项  在 config.m4 中 dnl 表示注释
config.m4 PHP_ARG_WITH  和 PHP_ARG_ENABLE  指定了 PHP 扩展模块的工作方式,前者意味着不需要第三方库,后者正好相反  if test "$PHP_MY_MODULE" != "no“ PHP_ADD_INCLUDE  指定 PHP 扩展模块用到的头文件目录  PHP_SUBST(MY_MODULE_SHARED_LIBADD)  用于说明这个扩展编译成动态链接库的形式
C -> C++ PHP core 是用 c 编写的,使用 c++ 的时候,需要在 config.m4 中增加参数 PHP_REQUIRE_CXX() PHP_ADD_LIBRARY(stdc++,"",MY_MODULE_SHARED_LIBADD)  PHP_NEW_EXTENSION(my_module, “my_module.cpp", $ext_shared) 修改 .c 变成 .cpp
C -> C++ 对于 ext_skel 生成的代码使用 extern “c” 来兼容纯 c 的代码 注:因为不同的编译器可能生成不同的中间符号名,所以用 extern 来修饰,具体参见 http://www.cppblog.com/Macaulish/archive/2008/06/17/53689.html
Add function 打开 php_my_module.h 找到 PHP_FUNCTION ,增加一行 PHP_FUNCTION(my_module_test);  打开 my_module.cpp 搜索 PHP_FE ,增加一行 PHP_FE(my_module_test, NULL) 增加 PHP_FUNCTION(my_module_test)
Coding function ZEND 的编程使用大量的宏,手册和对宏的了解是必不可少的 Output Input Handle Return
Output 使用 zend_printf 函数完成 output zend_error(E_ERROR, “xxx” ) 错误输出 E_ERROR E_WARNING E_NOTICE E_CORE_ERROR E_COMPILE_ERROR E_COMPILE_WARNING
Input ZEND_NUM_ARGS  () 取得传入参数数量 WRONG_PARAM_COUNT 抛出参数错误,终止程序
Input 使用 zend_parse_parameters 来取得参数 第一个参数表示需要解析的个数,可以使用  ZEND_NUM_ARGS()   来表示对传入的参数“有多少要多少”。 type_spec 是一个字符串,用来指定各个参数的类型,类似于  printf  中的参数格式化 ,当然后面的就是类似的变参,但是注意这里全部要使用参数的指针来获取
Input 参数类型 l -  长整数  d -  双精度浮点数  s -  字符串  ( 也可能是空字节 ) 和其长度  b -  布尔值  r -  资源 ,  保存在  zval*  a -  数组 ,  保存在  zval*  o -  (任何类的)对象 ,  保存在  zval*  O -  (由 class entry  指定的类的)对象 ,  保存在  zval*  z -  实际的  zval* | -  表明剩下的参数都是可选参数。如果用户没有传进来这些参数值,那么这些值就会被初始化成默认值。  / - the parsing function will call SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows, to provide a copy of the parameter, unless it's a reference  ! - the parameter it follows can be of specified type or NULL   (仅用在  a 、 o 、 O 、 r 和 z 身上)。如果用户传进来了一个  NULL   值,则存储该参数的变量将会设置为  NULL 。
Input Sample1
Input Sample2
Handle Exension 中处理部分最特殊的部分就是 php extension 中 c 的变量如何被 php 代码使用 两种交互方法 创建一个变量,加到 php 的变量容器中 创建一个变量,返回这个变量
PHP 访问 Zend 变量 创建 zval 容器 对 zval 结构进行填充 把 zval 引入 zend 的内部符号表中 从 php 端访问
变量作用域 全局变量 &EG(symbol_table)  局部变量 EG(active_symbol_table) 使用局部变量的时候要注意陷阱和段错误
加入符号表效率 宏 ZNED_SET_SYMBOL 首先检查变量是否已经存在于符号表中,如果已经存在则将其转换为一个引用变量(同时会自动销毁原有的  zval   容器)。速度较慢,节省内存 zend_hash_update 函数 强制更新符号表,速度较快,内存消耗稍多
变量赋值 zval 结构 value 存放 zval 的值, type 存放类型 zval 赋值
不同变量类型 IS_LONG  IS_DOUBLE  IS_STRING  IS_BOOL
数组变量赋值 数组在  Zend  内部是用哈希表( HashTable )来存储的 array_init(zval*) 来进行数组的初始化 使用 add_assoc_*()  和 add_index_*() add_assoc_long(zval *array, char *key, long n);  add_assoc_string(zval *array, char *key, char *str, int duplicate); add_index_long(zval *array, uint idx, long n); add_index_string(zval *array, uint idx, char *str, int duplicate);
数组变量赋值 因为数组变量是用 hash 表来管理的,使用 zend_hash_update(new_array->value.ht, key, strlen(key) + 1, (void *)&new_element, sizeof(zval *), NULL)  zend_hash_index_update(new_array->value.ht, key, (void *)&new_element, sizeof(zval *), NULL)
对象变量 Object like Array object_init()  初始化对象 使用 add_property_*() 函数 add_property_long(zval *object, char *key, long l);  add_property_string(zval *object, char *key, char *str, int duplicate); add_property_bool(zval *object, char *key, int b);
Return 返回值都是通过为  return_value   的变量传递的。这个参数是一个已经申请好空间的  zval   容器,无需先对  return_value   执行 MAKE_STD_ZVAL   宏指令。
Return 使用 RETURN_* 和 RETVAL_* 宏来完成 RETURN_BOOL(bool) 返回一个布尔值。 RETURN_NULL() 返回一个空值。 RETURN_LONG(long) 返回一个长整数。 RETVAL_LONG(long) 设定返回值为指定的一个长整数。 RETVAL_DOUBLE(double) 设定返回值为指定的一个双精度浮点数。 RETVAL_STRING(string, duplicate)
More to learn Extension 运行模式 内存管理 资源控制 Class … ..
Reference Zend API http://yanbin.org/archive/php-manual-hacking-the-code-of-php.html Extension Writing  http://devzone.zend.com/article/1021 http://my.huhoo.net/archives/2008/06/linuxcphp.html GOOGLE PHP.NET
Thank You

More Related Content

What's hot (20)

PPT
10 檔案說明與處理
shademoon
 
PPT
第六章 函數與巨集
shademoon
 
PDF
Posdll
guesta68668
 
PPT
1 C入門教學
Sita Liu
 
PPT
改善程序设计技术的50个有效做法
crasysatan
 
PPT
2009 CSBB LAB 新生訓練
Abner Huang
 
PDF
JavaScript现代化排错实践
jeffz
 
PDF
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
Li Hsuan Hung
 
DOCX
系統程式 - 第二章
鍾誠 陳鍾誠
 
PPT
Scala function-and-closures
wang hongjiang
 
DOC
Erlang jiacheng
Air-Smile
 
PDF
functional-scala
wang hongjiang
 
PPT
C語言 第4章 基本輸出與輸入功能
shademoon
 
PDF
系統程式 - 附錄
鍾誠 陳鍾誠
 
DOCX
系統程式 -- 附錄
鍾誠 陳鍾誠
 
PDF
系統程式 -- 第 11 章
鍾誠 陳鍾誠
 
PDF
LazyRecord: The Fast ORM for PHP
Lin Yo-An
 
PDF
cppcheck源码分析
Wu Liang
 
PDF
系統程式 -- 第 12 章
鍾誠 陳鍾誠
 
PPT
Device Driver - Chapter 6字元驅動程式的進階作業
ZongYing Lyu
 
10 檔案說明與處理
shademoon
 
第六章 函數與巨集
shademoon
 
Posdll
guesta68668
 
1 C入門教學
Sita Liu
 
改善程序设计技术的50个有效做法
crasysatan
 
2009 CSBB LAB 新生訓練
Abner Huang
 
JavaScript现代化排错实践
jeffz
 
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
Li Hsuan Hung
 
系統程式 - 第二章
鍾誠 陳鍾誠
 
Scala function-and-closures
wang hongjiang
 
Erlang jiacheng
Air-Smile
 
functional-scala
wang hongjiang
 
C語言 第4章 基本輸出與輸入功能
shademoon
 
系統程式 - 附錄
鍾誠 陳鍾誠
 
系統程式 -- 附錄
鍾誠 陳鍾誠
 
系統程式 -- 第 11 章
鍾誠 陳鍾誠
 
LazyRecord: The Fast ORM for PHP
Lin Yo-An
 
cppcheck源码分析
Wu Liang
 
系統程式 -- 第 12 章
鍾誠 陳鍾誠
 
Device Driver - Chapter 6字元驅動程式的進階作業
ZongYing Lyu
 

Viewers also liked (18)

PPT
资讯站与Sns的融合
thinkinlamp
 
PPT
正则表达式入门
thinkinlamp
 
PPT
Scrum pennygame
thinkinlamp
 
PDF
Mysql overview_20100811
thinkinlamp
 
PPT
优秀产品评赏
thinkinlamp
 
PPT
系统邮件实战技巧
thinkinlamp
 
PPT
基于架构的开发模式
thinkinlamp
 
PPT
面向搜索引擎的友好程序开发
thinkinlamp
 
PDF
MySQL高可用
thinkinlamp
 
PPT
符合语意的网页结构
thinkinlamp
 
PPT
I os tech talk 观后感
thinkinlamp
 
PPT
Lamp在51座席项目的应用
thinkinlamp
 
PPTX
大型互联网应用架构设计
thinkinlamp
 
PDF
Enterprise connect
thinkinlamp
 
PPSX
浅谈 My sql 性能调优
thinkinlamp
 
PPT
蜘蛛
thinkinlamp
 
PDF
2011 06-12-lamp-mysql-顾春江
thinkinlamp
 
PDF
Web development with zend framework
thinkinlamp
 
资讯站与Sns的融合
thinkinlamp
 
正则表达式入门
thinkinlamp
 
Scrum pennygame
thinkinlamp
 
Mysql overview_20100811
thinkinlamp
 
优秀产品评赏
thinkinlamp
 
系统邮件实战技巧
thinkinlamp
 
基于架构的开发模式
thinkinlamp
 
面向搜索引擎的友好程序开发
thinkinlamp
 
MySQL高可用
thinkinlamp
 
符合语意的网页结构
thinkinlamp
 
I os tech talk 观后感
thinkinlamp
 
Lamp在51座席项目的应用
thinkinlamp
 
大型互联网应用架构设计
thinkinlamp
 
Enterprise connect
thinkinlamp
 
浅谈 My sql 性能调优
thinkinlamp
 
蜘蛛
thinkinlamp
 
2011 06-12-lamp-mysql-顾春江
thinkinlamp
 
Web development with zend framework
thinkinlamp
 
Ad

Similar to Php extension开发 (9)

PDF
Internal php and gdb php core
alpha86
 
PDF
了解Php内核
Er Zhang
 
PPT
Php
pukongkong
 
PDF
Php for fe
jay li
 
PDF
iosdfoijehsogijlphpasjkdhiusghfripugsah;dfjkhs;kjfhi
1300672728
 
PDF
大话Php之性能
liqiang xu
 
PDF
Php调试技术手册发布(1.0.0 pdf)
lookforlk
 
PDF
OpenWebSchool - 02 - PHP Part I
Hung-yu Lin
 
PPTX
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
Liu Allen
 
Internal php and gdb php core
alpha86
 
了解Php内核
Er Zhang
 
Php for fe
jay li
 
iosdfoijehsogijlphpasjkdhiusghfripugsah;dfjkhs;kjfhi
1300672728
 
大话Php之性能
liqiang xu
 
Php调试技术手册发布(1.0.0 pdf)
lookforlk
 
OpenWebSchool - 02 - PHP Part I
Hung-yu Lin
 
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
Liu Allen
 
Ad

More from thinkinlamp (15)

PPT
数据仓库
thinkinlamp
 
PPSX
对My sql dba的一些思考
thinkinlamp
 
PPTX
云端的数据库
thinkinlamp
 
PDF
My sql innovation work -innosql
thinkinlamp
 
PPT
2011 06-12-why do we need the rabbit
thinkinlamp
 
PPTX
大型微博应用Feed系统浅析
thinkinlamp
 
PPT
网页游戏开发与敏捷开发
thinkinlamp
 
PPT
My sql自动化监控
thinkinlamp
 
PPTX
服务化的网站架构
thinkinlamp
 
PPT
Nosql七种武器之长生剑 mongodb的使用介绍
thinkinlamp
 
PPT
大型Sns数据库设计
thinkinlamp
 
PPT
别让专业水平外的因素拖
thinkinlamp
 
PPT
领域驱动设计
thinkinlamp
 
PPT
Scrum beyond software (think in lamp version)
thinkinlamp
 
PPT
数据处理算法设计要点
thinkinlamp
 
数据仓库
thinkinlamp
 
对My sql dba的一些思考
thinkinlamp
 
云端的数据库
thinkinlamp
 
My sql innovation work -innosql
thinkinlamp
 
2011 06-12-why do we need the rabbit
thinkinlamp
 
大型微博应用Feed系统浅析
thinkinlamp
 
网页游戏开发与敏捷开发
thinkinlamp
 
My sql自动化监控
thinkinlamp
 
服务化的网站架构
thinkinlamp
 
Nosql七种武器之长生剑 mongodb的使用介绍
thinkinlamp
 
大型Sns数据库设计
thinkinlamp
 
别让专业水平外的因素拖
thinkinlamp
 
领域驱动设计
thinkinlamp
 
Scrum beyond software (think in lamp version)
thinkinlamp
 
数据处理算法设计要点
thinkinlamp
 

Php extension开发

  • 2. What is Extension standard extension 自定义 extension
  • 3. What is Extension apc, mysqli 等都是 extension 默认放在 /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613 中 在 php.ini 中开启需要的 extension
  • 4. Extension 能做什么 和不同业务交互,接口是 C/C++ 接口,我们需要 extension 从 php 和这些接口交 互,协议接口 使用 extension 和共享内存交互,和高性能 c 程序完成高性能工作 - 数据库异步写操作 利用 c 的运算速度,完成高性能算法在 php 中的实现 将之前必须在 c 的环境下的工作,转移到 php 中 – 高性能 server 在 php 中的开发
  • 5. 今天的目标 Hello World 一个简单的加法运算函数
  • 6. 开发环境 Linux 系统 autoconfig php 源码 安装好的 php 环境 That‘s All ! Easy
  • 9. Begin 所有 extension 的编译环境都放在源代码的 Ext 子目录下 使用自动构建系统 ./ext_skel --extname = my_module 创建了名为 my_module 的文件夹
  • 10. config.m4 用于 Autoconfig, 用 m4 文件来处理宏生成需要的 configure 文件 config.m4 文件负责在配置时解析 configure 的命令行选项 在 config.m4 中 dnl 表示注释
  • 11. config.m4 PHP_ARG_WITH 和 PHP_ARG_ENABLE 指定了 PHP 扩展模块的工作方式,前者意味着不需要第三方库,后者正好相反 if test "$PHP_MY_MODULE" != "no“ PHP_ADD_INCLUDE 指定 PHP 扩展模块用到的头文件目录 PHP_SUBST(MY_MODULE_SHARED_LIBADD) 用于说明这个扩展编译成动态链接库的形式
  • 12. C -> C++ PHP core 是用 c 编写的,使用 c++ 的时候,需要在 config.m4 中增加参数 PHP_REQUIRE_CXX() PHP_ADD_LIBRARY(stdc++,"",MY_MODULE_SHARED_LIBADD) PHP_NEW_EXTENSION(my_module, “my_module.cpp", $ext_shared) 修改 .c 变成 .cpp
  • 13. C -> C++ 对于 ext_skel 生成的代码使用 extern “c” 来兼容纯 c 的代码 注:因为不同的编译器可能生成不同的中间符号名,所以用 extern 来修饰,具体参见 http://www.cppblog.com/Macaulish/archive/2008/06/17/53689.html
  • 14. Add function 打开 php_my_module.h 找到 PHP_FUNCTION ,增加一行 PHP_FUNCTION(my_module_test); 打开 my_module.cpp 搜索 PHP_FE ,增加一行 PHP_FE(my_module_test, NULL) 增加 PHP_FUNCTION(my_module_test)
  • 15. Coding function ZEND 的编程使用大量的宏,手册和对宏的了解是必不可少的 Output Input Handle Return
  • 16. Output 使用 zend_printf 函数完成 output zend_error(E_ERROR, “xxx” ) 错误输出 E_ERROR E_WARNING E_NOTICE E_CORE_ERROR E_COMPILE_ERROR E_COMPILE_WARNING
  • 17. Input ZEND_NUM_ARGS () 取得传入参数数量 WRONG_PARAM_COUNT 抛出参数错误,终止程序
  • 18. Input 使用 zend_parse_parameters 来取得参数 第一个参数表示需要解析的个数,可以使用 ZEND_NUM_ARGS() 来表示对传入的参数“有多少要多少”。 type_spec 是一个字符串,用来指定各个参数的类型,类似于 printf 中的参数格式化 ,当然后面的就是类似的变参,但是注意这里全部要使用参数的指针来获取
  • 19. Input 参数类型 l - 长整数 d - 双精度浮点数 s - 字符串 ( 也可能是空字节 ) 和其长度 b - 布尔值 r - 资源 , 保存在 zval* a - 数组 , 保存在 zval* o - (任何类的)对象 , 保存在 zval* O - (由 class entry 指定的类的)对象 , 保存在 zval* z - 实际的 zval* | - 表明剩下的参数都是可选参数。如果用户没有传进来这些参数值,那么这些值就会被初始化成默认值。 / - the parsing function will call SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows, to provide a copy of the parameter, unless it's a reference ! - the parameter it follows can be of specified type or NULL (仅用在 a 、 o 、 O 、 r 和 z 身上)。如果用户传进来了一个 NULL 值,则存储该参数的变量将会设置为 NULL 。
  • 22. Handle Exension 中处理部分最特殊的部分就是 php extension 中 c 的变量如何被 php 代码使用 两种交互方法 创建一个变量,加到 php 的变量容器中 创建一个变量,返回这个变量
  • 23. PHP 访问 Zend 变量 创建 zval 容器 对 zval 结构进行填充 把 zval 引入 zend 的内部符号表中 从 php 端访问
  • 24. 变量作用域 全局变量 &EG(symbol_table) 局部变量 EG(active_symbol_table) 使用局部变量的时候要注意陷阱和段错误
  • 25. 加入符号表效率 宏 ZNED_SET_SYMBOL 首先检查变量是否已经存在于符号表中,如果已经存在则将其转换为一个引用变量(同时会自动销毁原有的 zval 容器)。速度较慢,节省内存 zend_hash_update 函数 强制更新符号表,速度较快,内存消耗稍多
  • 26. 变量赋值 zval 结构 value 存放 zval 的值, type 存放类型 zval 赋值
  • 27. 不同变量类型 IS_LONG IS_DOUBLE IS_STRING IS_BOOL
  • 28. 数组变量赋值 数组在 Zend 内部是用哈希表( HashTable )来存储的 array_init(zval*) 来进行数组的初始化 使用 add_assoc_*() 和 add_index_*() add_assoc_long(zval *array, char *key, long n); add_assoc_string(zval *array, char *key, char *str, int duplicate); add_index_long(zval *array, uint idx, long n); add_index_string(zval *array, uint idx, char *str, int duplicate);
  • 29. 数组变量赋值 因为数组变量是用 hash 表来管理的,使用 zend_hash_update(new_array->value.ht, key, strlen(key) + 1, (void *)&new_element, sizeof(zval *), NULL) zend_hash_index_update(new_array->value.ht, key, (void *)&new_element, sizeof(zval *), NULL)
  • 30. 对象变量 Object like Array object_init() 初始化对象 使用 add_property_*() 函数 add_property_long(zval *object, char *key, long l); add_property_string(zval *object, char *key, char *str, int duplicate); add_property_bool(zval *object, char *key, int b);
  • 31. Return 返回值都是通过为 return_value 的变量传递的。这个参数是一个已经申请好空间的 zval 容器,无需先对 return_value 执行 MAKE_STD_ZVAL 宏指令。
  • 32. Return 使用 RETURN_* 和 RETVAL_* 宏来完成 RETURN_BOOL(bool) 返回一个布尔值。 RETURN_NULL() 返回一个空值。 RETURN_LONG(long) 返回一个长整数。 RETVAL_LONG(long) 设定返回值为指定的一个长整数。 RETVAL_DOUBLE(double) 设定返回值为指定的一个双精度浮点数。 RETVAL_STRING(string, duplicate)
  • 33. More to learn Extension 运行模式 内存管理 资源控制 Class … ..
  • 34. Reference Zend API http://yanbin.org/archive/php-manual-hacking-the-code-of-php.html Extension Writing http://devzone.zend.com/article/1021 http://my.huhoo.net/archives/2008/06/linuxcphp.html GOOGLE PHP.NET