mydeer
就像我们从来没有来过这里,但这种感觉似曾相识。
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.
<< 上一篇 Linux虚拟内存 TCP的建立和释放 下一篇 >>
文章标签
随意 | Created At 2014 By William Clinton | 蜀ICP备14002619号-4 |