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.