PHP扩展开发 -- 创建一个类 Class
我们要实现以下PHP代码实现的功能:
class Person { private $_name; public function __construct() { echo "__construct called."; } public function __destruct() { echo "__destruct called."; } public function getname() { return $this->_name; } public function setname($val) { $this->_name = $val; } }
来开始我们的第一个 类 Class 的PHP扩展编写
1、首先进入PHP的源码扩展,建立扩展框架
cd ./ext/ ./ext_skel --extname=Person
2、修改config.m4,去掉以下三行的dnl
PHP_ARG_WITH(Person, for Person support, Make sure that the comment is aligned: [ --with-Person Include Person support])
3、修改php_Person.h,末尾追加
PHP_METHOD(Person,__construct); PHP_METHOD(Person,__destruct); PHP_METHOD(Person,setname); PHP_METHOD(Person,getname);
4、修改Person.c,这是重点,实现Person类
- 设置接收的参数,我们的方法需要接受参数.那么就要执行
添加以下三行
ZEND_BEGIN_ARG_INFO(arg_person_setname, 0) ZEND_ARG_INFO(0, name) ZEND_END_ARG_INFO()
- 注册到函数:声明方法的参数,并注册到函数表中。
修改 const zend_function_entry Person_functions[]
const 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, getname, NULL, ZEND_ACC_PUBLIC) PHP_ME(Person, setname, arg_person_setname, ZEND_ACC_PUBLIC) PHP_FE_END };
- PHP_MINIT_FUNCTION是在模块启动的时候执行的函数
首先创建一个全局指针 zend_class_entry *person_ce;
添加一行
zend_class_entry *person_ce;
修改PHP_MINIT_FUNCTION(Person)
PHP_MINIT_FUNCTION(Person) { zend_class_entry person; INIT_CLASS_ENTRY(person,"Person",Person_functions); person_ce = zend_register_internal_class_ex(&person,NULL,NULL TSRMLS_CC); zend_declare_property_null(person_ce,ZEND_STRL("_name"),ZEND_ACC_PRIVATE TSRMLS_CC); return SUCCESS; }
最后是类中具体方式实现
添加,构造函数和析构函数中只是输出一些文本
PHP_METHOD(Person,__construct){ php_printf("__construct called."); } PHP_METHOD(Person,__destruct){ php_printf("__destruct called."); } PHP_METHOD(Person,getname){ zval *self,*name; self = getThis(); name = zend_read_property(Z_OBJCE_P(self),self,ZEND_STRL("_name"),0 TSRMLS_CC); RETURN_STRING(Z_STRVAL_P(name),0); } PHP_METHOD(Person,setname){ char *arg = NULL; int arg_len; zval *value ,*self; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"s",&arg,&arg_len) == FAILURE ){ WRONG_PARAM_COUNT; } self = getThis(); ALLOC_INIT_ZVAL(value); //MAKE_STD_ZVAL(value); ZVAL_STRINGL(value,arg,arg_len,0); SEPARATE_ZVAL_TO_MAKE_IS_REF(&value); zend_update_property(Z_OBJCE_P(self),self,ZEND_STRL("_name"),value TSRMLS_CC); RETURN_TRUE; }
5、编译并追加PHP扩展,命令行执行
phpize ./configure make // 扩展拷贝到PHP下 cp modules/Person.so /usr/lib64/php/modules/ // 修改配置PHP文件,追加 vim /etc/php.ini extension=Person.so
6、测试
测试php代码
<?php $obj = new Person(); $obj->setname("hello"); echo "\n",$obj->getname(),"\n"; ?>
执行结果:
__construct called. hello __destruct called.