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

news/2024/7/4 1:33:51 标签: php, 扩展, zend, class, null, reference
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

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

上一章用class="tags" href="/tags/KuoZhan.html" title=扩展>扩展创建了一个变量..

这次来个大的..我们创建一个类.
然后在class="tags" href="/tags/PHP.html" title=php>php里面去调用这个类.
生成class="tags" href="/tags/KuoZhan.html" title=扩展>扩展及修改 不知道的请点击这里    http://imsiren.com/archives/568
这里就不谈了.
比如我们要创建一个类..PHP代码如下
class="language-class="tags" href="/tags/PHP.html" title=php>php">class Person {
    public $name;
    public $age;
    public function __construct() {
        echo "construct is running!
";
    }
    public function __destruct() {
        echo "
destruct is running!";
    }
    public function getproperty($key) {
        echo $this->$key;
    }
    public function setproperty($key,$val) {
        $this->$key = $val;
    }
}
用PHP来做,很简单..
那么用PHPclass="tags" href="/tags/KuoZhan.html" title=扩展>扩展来写该怎么做?
OK.

1.在class="tags" href="/tags/PHP.html" title=php>php_siren.h里面声明类


class="language-java">PHP_METHOD(Person,__construct);
PHP_METHOD(Person,__destruct);
PHP_METHOD(Person,setproperty);
PHP_METHOD(Person,getproperty);

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

class="language-cpp">#define ZEND_METHOD(classname, name)    ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v    alue_used TSRMLS_DC
//最后等于
void name(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v    alue_used TSRMLS_DC )

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

class="language-cpp">ZEND_BEGIN_ARG_INFO_EX(arg_person_info,0,0,2) 
        ZEND_ARG_INFO(0,name)
ZEND_END_ARG_INFO()

详细讲这几个宏之前先看看class="tags" href="/tags/ZEND.html" title=zend>zend_arg_info

class="language-cpp">typedef struct _class="tags" href="/tags/ZEND.html" title=zend>zend_arg_info {
        const char *name; //参数名称
        class="tags" href="/tags/ZEND.html" title=zend>zend_uint name_len;//长度
        const char *class_name;  //所属类名
        class="tags" href="/tags/ZEND.html" title=zend>zend_uint class_name_len;  //类名长度
        class="tags" href="/tags/ZEND.html" title=zend>zend_bool array_type_hint;
        class="tags" href="/tags/ZEND.html" title=zend>zend_bool allow_null; //允许为空
        class="tags" href="/tags/ZEND.html" title=zend>zend_bool pass_by_reference;  //引用传值
        class="tags" href="/tags/ZEND.html" title=zend>zend_bool return_reference;   //引用返回
        int required_num_args;   //参数个数
} class="tags" href="/tags/ZEND.html" title=zend>zend_arg_info;

ZEND_BEGIN_ARG_INFO_EX定义在Zend/class="tags" href="/tags/ZEND.html" title=zend>zend_API.h 

class="language-cpp">#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args)       \
        static const class="tags" href="/tags/ZEND.html" title=zend>zend_arg_info name[] = {                                                                                                                                           \
                { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },

很明显 声明一个class="tags" href="/tags/ZEND.html" title=zend>zend_arg_info的数组name,然后初始化结构体的值
ZEND_ARG_INFO(0,name)的定义如下

class="language-cpp">#define ZEND_ARG_INFO(pass_by_ref, name)  { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },

这三个宏 执行代码 等于

class="language-cpp">static const class="tags" href="/tags/ZEND.html" title=zend>zend_arg_info name[] = {                                                                                                                                                    { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
{ #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
};

3.创建class="tags" href="/tags/ZEND.html" title=zend>zend_function_entry结构数组

class="language-cpp">const class="tags" href="/tags/ZEND.html" title=zend>zend_function_entry person_functions[]={
        PHP_ME(Person,__construct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
        PHP_ME(Person,__destruct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
        PHP_ME(Person,getproperty,arg_person_info,ZEND_ACC_PUBLIC)
        PHP_ME(Person,setproperty,arg_person_info,ZEND_ACC_PUBLIC)
        PHP_FE_END
};
class="language-cpp">
class="language-cpp">class="tags" href="/tags/ZEND.html" title=zend>zend_function_entry定义如下

class="cpp">class="language-cpp">typedef struct _class="tags" href="/tags/ZEND.html" title=zend>zend_function_entry {
        const char *fname; //函数名称
        void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
        const struct _class="tags" href="/tags/ZEND.html" title=zend>zend_arg_info *arg_info;//参数
        class="tags" href="/tags/ZEND.html" title=zend>zend_uint num_args;//参数个数
        class="tags" href="/tags/ZEND.html" title=zend>zend_uint flags;//标示PUBLIC ?PRIVATE ?PROTECTED
} class="tags" href="/tags/ZEND.html" title=zend>zend_function_entry;

PHP_ME宏接收四个参数
1 类名,
2 方法名,
3 class="tags" href="/tags/ZEND.html" title=zend>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是在模块启动的时候执行的函数
首先创建一个全局指针 class="tags" href="/tags/ZEND.html" title=zend>zend_class_entry *person_ce;
在PHP_MINIT_FUNCTION加入如下代码

class="language-cpp">class="tags" href="/tags/ZEND.html" title=zend>zend_class_entry person;
INIT_CLASS_ENTRY(person,"Person",person_functions);
person_ce=class="tags" href="/tags/ZEND.html" title=zend>zend_register_internal_class_ex(&person,NULL,NULL TSRMLS_CC);
class="tags" href="/tags/ZEND.html" title=zend>zend_declare_property_null(person_ce,ZEND_STRL("name"),ZEND_ACC_PUBLIC TSRMLS_CC);

1行创建一个class="tags" href="/tags/ZEND.html" title=zend>zend_class_entry对象person.
class="tags" href="/tags/ZEND.html" title=zend>zend_class_entry这个结构体前面也讲过 PHP内核研究之类的实现 
2行初始化class="tags" href="/tags/ZEND.html" title=zend>zend_class_entry 它执行了如下代码

class="language-cpp">       {                                                                                                                       \
                int _len = class_name_len;                                                              \
                class_container.name = class="tags" href="/tags/ZEND.html" title=zend>zend_strndup(class_name, _len);  \
                class_container.name_length = _len;                                             \
                class_container.builtin_functions = functions;                  \
                class_container.constructor = NULL;                                             \
                class_container.destructor = NULL;                                              \
                class_container.clone = NULL;                                                   \
                class_container.serialize = NULL;                                               \
                class_container.unserialize = NULL;                                             \
                class_container.create_object = NULL;                                   \
                class_container.interface_gets_implemented = NULL;              \
                class_container.get_static_method = NULL;                               \
                class_container.__call = handle_fcall;                                  \
                class_container.__callstatic = NULL;                                    \
                class_container.__tostring = NULL;                                              \
                class_container.__get = handle_propget;                                 \
                class_container.__set = handle_propset;                                 \
                class_container.__unset = handle_propunset;                             \
                class_container.__isset = handle_propisset;                             \
                class_container.serialize_func = NULL;                                  \
                class_container.unserialize_func = NULL;                                \
                class_container.serialize = NULL;                                               \
                class_container.unserialize = NULL;                                             \
                class_container.parent = NULL;                                                  \
                class_container.num_interfaces = 0;                                             \
                class_container.interfaces = NULL;                                              \
                class_container.get_iterator = NULL;                                    \
                class_container.iterator_funcs.funcs = NULL;                    \
                class_container.module = NULL;                                                  \
        }

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

5.创建 class="tags" href="/tags/PHP.html" title=php>php_siren.h头文件中的方法体

class="language-cpp">PHP_METHOD(Person,__construct){
        class="tags" href="/tags/PHP.html" title=php>php_printf("construct is running<br>");
}
PHP_METHOD(Person,__destruct){
        class="tags" href="/tags/PHP.html" title=php>php_printf("destruct is running<br>");
}
PHP_METHOD(Person,setproperty){

}
PHP_METHOD(Person,getproperty){

}

6.最后make&& make install

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


construct is running
destruct is running


这样 ..我们用class="tags" href="/tags/KuoZhan.html" title=扩展>扩展创建的一个基本类就完成了.


http://www.niftyadmin.cn/n/1790446.html

相关文章

es6冲刺02

1、Symbol es6新增的数据类型 1&#xff09;概念 提供一个独一无二的值 let aSymbol() let bSymbol() 或 let cSymbol.for(c) let dSymbol.for(c) c是一个key&#xff0c;标识着这个独一无二的变量 2、数据结构 1)set Set中的元素不可重复 其长度用.size表征 添加重复元素&…

自己写PHP扩展之操作类的属性和方法

声明&#xff1a;本文为斯人原创&#xff0c;全部为作者一一分析得之&#xff0c;有不对的地方望赐教。欢迎转载&#xff0c;转载请注明出处 。本文地址&#xff1a;http://imsiren.com/archives/581类创建好了..那么类肯定不止这些东西,它由继承,属性,返回值等.1.方法的参数.有…

爬虫vs反爬虫

爬虫介绍 爬虫简单介绍就是一个获取数据的途径。有时我们需要进行数据分析等操作&#xff0c;都会将别人网站中现成的数据放入我们自己本地数据库内&#xff0c;这时候&#xff0c;我们可以使用爬虫来实现。 网站的重要资料、信息财产被轻易窃取&#xff0c;是不能随便泄漏的。…

pinicTable

def printTable(dic_name,l_length,r_length):print(ITEM TABLE.center(l_lengthr_length,"-"))for k,v in dic_name.items():print(str(k).ljust(l_length,.)str(v).rjust(r_length, ))#填充内容至少为一个character&#xff0c;不能用,应该输入一个spacepicnicItem…

自己写PHP扩展之实现类的继承

声明&#xff1a;本文为 斯人原创&#xff0c;全部为作者一一分析得之&#xff0c;有不对的地方望赐教。 欢迎转载&#xff0c;转载请注明出处 。 本文地址&#xff1a; http://imsiren.com/archives/593如果我们想继承某一个类,我们怎么办?比如 Siren类继承Secure类.class Se…

C++与类型转换相关的四个关键字及其特点

1、reinterpret_cast (expression) type-id 必须是一个指针、引用、算术类型、函数指针或者成员指针。 它可以把一个指针转换成一个整数&#xff0c;也可以把一个整数转换成一个指针&#xff08;先把一个指针转换成一个整数&#xff0c;再把该整数转换成原类型的指针&#xff0…

原:PHP内核函数研究之 global

声明&#xff1a;本文为斯人原创&#xff0c;全部为作者一一分析得之&#xff0c;有不对的地方望赐教。 欢迎转载&#xff0c;转载请注明出处 。本文地址&#xff1a;http://imsiren.com/archives/601好久没有写博客了…最近事挺多,换了工作,又搬了家..今天就来说说 我们经常用…

win10安装3DSMAX失败,怎么强力卸载删除注册表并重新安装

一些搞设计的朋友在win10系统下安装3DSMAX失败或提示已安装&#xff0c;也有时候想重新安装3DSMAX的时候会出现本电脑windows系统已安装3DSMAX&#xff0c;你要是不留意直接安装3DSMAX&#xff0c;只会安装3DSMAX的附件或者直接提示失败&#xff0c;3DSMAX是不会安装上的。这种…