自己写PHP扩展之创建一个类

声明:本文为斯人原创,全部为作者一一分析得之,有不对的地方望赐教。
欢迎转载,转载请注明出处 。
本文地址:http://imsiren.com/archives/572

上一章用扩展创建了一个变量..

这次来个大的..我们创建一个类.
然后在php里面去调用这个类.
生成扩展及修改 不知道的请点击这里    http://imsiren.com/archives/568
这里就不谈了.
比如我们要创建一个类..PHP代码如下
[php]  view plain copy
  1. class Person {  
  2.     public $name;  
  3.     public $age;  
  4.     public function __construct() {  
  5.         echo "construct is running!  
  6. ";  
  7.     }  
  8.     public function __destruct() {  
  9.         echo "  
  10. destruct is running!";  
  11.     }  
  12.     public function getproperty($key) {  
  13.         echo $this->$key;  
  14.     }  
  15.     public function setproperty($key,$val) {  
  16.         $this->$key = $val;  
  17.     }  
  18. }  
用PHP来做,很简单..
那么用PHP扩展来写该怎么做?
OK.

1.在php_siren.h里面声明类


[java]  view plain copy
  1. PHP_METHOD(Person,__construct);  
  2. PHP_METHOD(Person,__destruct);  
  3. PHP_METHOD(Person,setproperty);  
  4. PHP_METHOD(Person,getproperty);  

PHP_METHOD宏.
PHP_METHOD 等于ZEND_METHOD
这个宏接受两个参数,第一个是类名,第二个是类的方法

[cpp]  view plain copy
  1. #define ZEND_METHOD(classname, name)    ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))  
  2. #define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v    alue_used TSRMLS_DC  
  3. //最后等于  
  4. void name(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v    alue_used TSRMLS_DC )  

这个宏是用来声明我们的方法...
2.设置接收的参数
我们的方法如果需要接受参数.那么就要执行 

[cpp]  view plain copy
  1. ZEND_BEGIN_ARG_INFO_EX(arg_person_info,0,0,2)   
  2.         ZEND_ARG_INFO(0,name)  
  3. ZEND_END_ARG_INFO()  

详细讲这几个宏之前先看看zend_arg_info

[cpp]  view plain copy
  1. typedef struct _zend_arg_info {  
  2.         const char *name; //参数名称  
  3.         zend_uint name_len;//长度  
  4.         const char *class_name;  //所属类名  
  5.         zend_uint class_name_len;  //类名长度  
  6.         zend_bool array_type_hint;  
  7.         zend_bool allow_null; //允许为空  
  8.         zend_bool pass_by_reference;  //引用传值  
  9.         zend_bool return_reference;   //引用返回  
  10.         int required_num_args;   //参数个数  
  11. } zend_arg_info;  

ZEND_BEGIN_ARG_INFO_EX定义在Zend/zend_API.h 

[cpp]  view plain copy
  1. #define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args)       \  
  2.         static const zend_arg_info name[] = {                                                                                                                                           \  
  3.                 { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },  

很明显 声明一个zend_arg_info的数组name,然后初始化结构体的值
ZEND_ARG_INFO(0,name)的定义如下

[cpp]  view plain copy
  1. #define ZEND_ARG_INFO(pass_by_ref, name)  { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },  

这三个宏 执行代码 等于

[cpp]  view plain copy
  1. static const zend_arg_info name[] = {                                                                                                                                                    { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },  
  2. { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },  
  3. };  

3.创建zend_function_entry结构数组

[cpp]  view plain copy
  1. const zend_function_entry person_functions[]={  
  2.         PHP_ME(Person,__construct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)  
  3.         PHP_ME(Person,__destruct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)  
  4.         PHP_ME(Person,getproperty,arg_person_info,ZEND_ACC_PUBLIC)  
  5.         PHP_ME(Person,setproperty,arg_person_info,ZEND_ACC_PUBLIC)  
  6.         PHP_FE_END  
  7. };  
[cpp]  view plain copy
  1.   
zend_function_entry定义如下

[cpp]  view plain copy
  1. typedef struct _zend_function_entry {  
  2.         const char *fname; //函数名称  
  3.         void (*handler)(INTERNAL_FUNCTION_PARAMETERS);  
  4.         const struct _zend_arg_info *arg_info;//参数  
  5.         zend_uint num_args;//参数个数  
  6.         zend_uint flags;//标示PUBLIC ?PRIVATE ?PROTECTED  
  7. } zend_function_entry;  

PHP_ME宏接收四个参数
1 类名,
2 方法名,
3 zend_arg_info 的参数列表,


ZEND_ACC_PUBLIC ZEND_ACC_PRIVATE ZEND_ACC_PROTECTED是我们类里面的三个访问权限
ZEND_ACC_CTOR标示构造函数
ZEND_ACC_DTOR标示析构函数

4.修改PHP_MINIT_FUNCTION
前面我们说过 PHP_MINIT_FUNCTION是在模块启动的时候执行的函数
首先创建一个全局指针 zend_class_entry *person_ce;
在PHP_MINIT_FUNCTION加入如下代码

[cpp]  view plain copy
  1. zend_class_entry person;  
  2. INIT_CLASS_ENTRY(person,"Person",person_functions);  
  3. person_ce=zend_register_internal_class_ex(&person,NULL,NULL TSRMLS_CC);  
  4. zend_declare_property_null(person_ce,ZEND_STRL("name"),ZEND_ACC_PUBLIC TSRMLS_CC);  

1行创建一个zend_class_entry对象person.
zend_class_entry这个结构体前面也讲过  PHP内核研究之类的实现 
2行初始化zend_class_entry 它执行了如下代码

[cpp]  view plain copy
  1. {                                                                                                                       \  
  2.          int _len = class_name_len;                                                              \  
  3.          class_container.name = zend_strndup(class_name, _len);  \  
  4.          class_container.name_length = _len;                                             \  
  5.          class_container.builtin_functions = functions;                  \  
  6.          class_container.constructor = NULL;                                             \  
  7.          class_container.destructor = NULL;                                              \  
  8.          class_container.clone = NULL;                                                   \  
  9.          class_container.serialize = NULL;                                               \  
  10.          class_container.unserialize = NULL;                                             \  
  11.          class_container.create_object = NULL;                                   \  
  12.          class_container.interface_gets_implemented = NULL;              \  
  13.          class_container.get_static_method = NULL;                               \  
  14.          class_container.__call = handle_fcall;                                  \  
  15.          class_container.__callstatic = NULL;                                    \  
  16.          class_container.__tostring = NULL;                                              \  
  17.          class_container.__get = handle_propget;                                 \  
  18.          class_container.__set = handle_propset;                                 \  
  19.          class_container.__unset = handle_propunset;                             \  
  20.          class_container.__isset = handle_propisset;                             \  
  21.          class_container.serialize_func = NULL;                                  \  
  22.          class_container.unserialize_func = NULL;                                \  
  23.          class_container.serialize = NULL;                                               \  
  24.          class_container.unserialize = NULL;                                             \  
  25.          class_container.parent = NULL;                                                  \  
  26.          class_container.num_interfaces = 0;                                             \  
  27.          class_container.interfaces = NULL;                                              \  
  28.          class_container.get_iterator = NULL;                                    \  
  29.          class_container.iterator_funcs.funcs = NULL;                    \  
  30.          class_container.module = NULL;                                                  \  
  31.  }  

可以对应  PHP内核研究之类的实现  来分析

5.创建 php_siren.h头文件中的方法体

[cpp]  view plain copy
  1. PHP_METHOD(Person,__construct){  
  2.         php_printf("construct is running<br>");  
  3. }  
  4. PHP_METHOD(Person,__destruct){  
  5.         php_printf("destruct is running<br>");  
  6. }  
  7. PHP_METHOD(Person,setproperty){  
  8.   
  9. }  
  10. PHP_METHOD(Person,getproperty){  
  11.   
  12. }  

6.最后make&& make install

编译我们的扩展,
重新启动apache.
<?php
$p=new Person();
?>
我们就能在浏览器里看到输出的内容


construct is running
destruct is running


这样 ..我们用扩展创建的一个基本类就完成了.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

anssummer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值