zoukankan      html  css  js  c++  java
  • PHP扩展开发之简单类开发

    接下来我们要用扩展的形式实现以下类(演示环境:linux、php-5.5.34-src)

     1 <?php 
     2 class Person
     3 {
     4     private $_name;
     5     public function getName()
     6     {
     7         return $this -> _name;
     8     } 
     9     public function setName($name)
    10     {
    11         $this -> _name = $name;
    12     } 
    13 } 

    在PHP源码目录下

    1 cd php-5.5.34-src
    2 cd ext
    3 ./ext_skel --extname=hdx  //生成hdx扩展骨架
    4 cd hdx

    1.修改config.m4

    PHP_ARG_WITH(hdx, for hdx support,    
    [  --with-hdx             Include hdx support])
    
    //把这两行前面的dnl去掉  大概在 10-12行

    2.在hdx.h添加如下

    PHP_METHOD(Person, __construct);
    PHP_METHOD(Person, __destruct);
    PHP_METHOD(Person, getName);
    PHP_METHOD(Person, setName);

    3.在hdx.c下方添加相应函数

     1 PHP_METHOD(Person, __construct) {
     2  php_printf("__construct called.");
     3 }
     4 
     5 PHP_METHOD(Person, __destruct) {
     6  php_printf("__destruct called.<br/>");
     7 }
     8 
     9 PHP_METHOD(Person, getName) {
    10  zval *self, *name;
    11  self = getThis();
    12  name = zend_read_property(Z_OBJCE_P(self), self, ZEND_STRL("_name"), 0 TSRMLS_CC);
    13  RETURN_STRING(Z_STRVAL_P(name), 0);
    14 }
    15 
    16 PHP_METHOD(Person, setName) {
    17  char *arg = NULL;
    18  int arg_len;
    19  zval *value, *self;
    20  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
    21  WRONG_PARAM_COUNT;
    22  }
    23  self = getThis();
    24  MAKE_STD_ZVAL(value);
    25  ZVAL_STRINGL(value, arg, arg_len, 0);
    26  SEPARATE_ZVAL_TO_MAKE_IS_REF(&value);
    27  zend_update_property(Z_OBJCE_P(self), self, ZEND_STRL("_name"), value TSRMLS_CC);
    28  RETURN_TRUE;
    29 }

    对上面的代码做一些解释:

    A. 获取方法的参数信息,仍然使用zend_parse_parameters函数,与之前我们介绍过的一样;

    B. 获取this指针(相对于PHP代码而言,在PHP扩展中仍然使用zval结构表示)使用getThis()函数;

    C. 使用MAKE_STD_ZVAL宏申请并初始化一个zval结构,在PHP扩展中,所有的数据类型其实都是用zval结构来表示的,在本系列文章中我会单独写一篇来介绍zval。

    D. 获取属性值使用zend_read_property()函数,使用zend_update_property()函数更新属性值。

    4.在hdx.c 上方,初始化类:在扩展初始化函数中,注册并初始化类。

    1 zend_class_entry *person_ce;
    2 
    3 PHP_MINIT_FUNCTION(fetion_echo)
    4 { 
    5     zend_class_entry person; 
    INIT_CLASS_ENTRY(person, "Person", fetion_echo_functions); 6 person_ce = zend_register_internal_class_ex(&person, NULL, NULL TSRMLS_CC); 7 8 zend_declare_property_null(person_ce, ZEND_STRL("_name"), ZEND_ACC_PRIVATE TSRMLS_CC); return SUCCESS; 9 }

    使用INIT_CLASS_ENTRY宏初始化类,第二个参数指定类名,第三个参数是函数表。

    5. 注册到函数:声明方法的参数,并注册到函数表中。

    1 ZEND_BEGIN_ARG_INFO(arg_person_setname, 0)
    2     ZEND_ARG_INFO(0, name)
    3 ZEND_END_ARG_INFO() const zend_function_entry fetion_echo_functions[] = {
    4     PHP_ME(Person, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
    5     PHP_ME(Person, __destruct,  NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
    6     PHP_ME(Person, getName,     NULL, ZEND_ACC_PUBLIC)
    7     PHP_ME(Person, setName,     arg_person_setname, ZEND_ACC_PUBLIC)
    8     {NULL, NULL, NULL} /* Must be the last line in fetion_echo_functions[] */ };

    类方法参数的声明与之前我们函数参数声明方式一致,在注册类方法到函数表中时使用PHP_ME宏,而不是之前使用的PHP_FE宏。

    ZEND_ACC_PUBLIC:指定方法的访问修饰符

    ZEND_ACC_CTOR:指定该方法为构造函数

    ZEND_ACC_DTOR:指定该方法为析构函数

    6.安装

    1 /usr/local/php/bin/phpize
    2 ./configure --with-php-config=/usr/local/php/bin/php-config
    3 make && make install

    然后在PHP安装目录下修改php.ini把扩展添加上

    7. 运行测试:编译安装扩展后,编写一段简单的测试脚本:

    1 <?php 
    2 $person = new Person();
    3 $person->setName("huangdongxi"); 
    4 echo $person->getName().'<br/>';

    运行后可以看到如下输出,说明扩展工作正常:
    __construct called.
    huangdongxi
    __destruct called.

  • 相关阅读:
    This counter can increment, decrement or skip ahead by an arbitrary amount
    LUT4/MUXF5/MUXF6 logic : Multiplexer 8:1
    synthesisable VHDL for a fixed ratio frequency divider
    Bucket Brigade FIFO SRL16E ( VHDL )
    srl16e fifo verilog
    DualPort Block RAM with Two Write Ports and Bytewide Write Enable in ReadFirst Mode
    Parametrilayze based on SRL16 shift register FIFO
    stm32 spi sdcard fatfs
    SPI bus master for System09 (2)
    SQLSERVER中的自旋锁
  • 原文地址:https://www.cnblogs.com/guaidaodark/p/5746313.html
Copyright © 2011-2022 走看看