php扩展练习-类

来源:互联网 发布:集贤第一中学网络空间 编辑:程序博客网 时间:2024/06/05 17:47

前言

  本篇博文是对PHP扩展开发及内核应用第10-11章的学习、练习、总结。
  

练习习题

  用php扩展实现

        abstract class My_Yaf_Request_Abstract        {            protected $action;            public function __construct()            {                echo "I am My_Yaf_Request_Abstract\n";            }            public function setActionName($action_name)            {                $this->action = $action_name;            }            public function getActionName()            {                return $this->action;            }            public abstract function isCli();        }        class My_Yaf_Request_Http extends My_Yaf_Request_Abstract        {            public function __construct()            {                echo("I am My_Yaf_Request_Http\n");            }            public function isCli()            {                return false;            }        }        class My_Yaf_Request_Simple extends My_Yaf_Request_Abstract        {            public function __construct()            {                echo("I am My_Yaf_Request_Simple\n");            }            public function isCli()            {                return true;            }        }

实现

  PHP扩展开发及内核应用中对类的实现已经讲得十分详细,直接贴上我的实现吧。

    //myyaf.c    #include "myyaf.h"    //module entry    #ifdef COMPILE_DL_MYYAF    zend_class_entry *my_yaf_request_abstract;    zend_class_entry *my_yaf_request_http;    zend_class_entry *my_yaf_request_simple;    ZEND_METHOD(My_Yaf_Request_Abstract, __construct)    {            php_printf("I am My_Yaf_Request_Abstract\n");        }    ZEND_METHOD(My_Yaf_Request_Abstract, isCli)    {    }    ZEND_METHOD(My_Yaf_Request_Abstract, setActionName)    {            zval *action;            zend_class_entry *ce;            ce = Z_OBJCE_P(getThis());            if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &action) == FAILURE )            {                   printf("Error\n");                RETURN_NULL();            }            zend_update_property(ce, getThis(), "action", sizeof("action")-1, action TSRMLS_CC);    }    ZEND_METHOD(My_Yaf_Request_Abstract, getActionName)    {            zval *action;            zend_class_entry *ce;            ce = Z_OBJCE_P(getThis());            action = zend_read_property(ce, getThis(), "action", sizeof("action")-1, 1 TSRMLS_DC);            RETVAL_ZVAL(action,1,0);    }    ZEND_METHOD(My_Yaf_Request_Http, __construct)    {            php_printf("I am My_Yaf_Request_Http\n");    }    ZEND_METHOD(My_Yaf_Request_Http, isCli)    {            RETVAL_BOOL(0);    }    ZEND_METHOD(My_Yaf_Request_Simple, __construct)    {            php_printf("I am My_Yaf_Request_Simple\n");    }    ZEND_METHOD(My_Yaf_Request_Simple, isCli)    {            RETVAL_BOOL(1);    }    static zend_function_entry my_yaf_request_abstract_method[] = {            ZEND_ME(My_Yaf_Request_Abstract, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)            ZEND_ME(My_Yaf_Request_Abstract, getActionName, NULL, ZEND_ACC_PUBLIC)            ZEND_ME(My_Yaf_Request_Abstract, setActionName, NULL, ZEND_ACC_PUBLIC)            ZEND_ME(My_Yaf_Request_Abstract, isCli, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT)            ZEND_ME(My_Yaf_Request_Abstract, isCli, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT)            {NULL, NULL, NULL}    };    static zend_function_entry my_yaf_request_http_method[] = {            ZEND_ME(My_Yaf_Request_Http, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)            ZEND_ME(My_Yaf_Request_Http, isCli, NULL, ZEND_ACC_PUBLIC)            {NULL, NULL, NULL}    };    static zend_function_entry my_yaf_request_simple_method[] = {            ZEND_ME(My_Yaf_Request_Simple, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)            ZEND_ME(My_Yaf_Request_Simple, isCli, NULL, ZEND_ACC_PUBLIC)            {NULL, NULL, NULL}    };    ZEND_MINIT_FUNCTION(myyaf)    {            zend_class_entry ce, http_ce, simple_ce;            INIT_CLASS_ENTRY(ce, "My_Yaf_Request_Abstract", my_yaf_request_abstract_method);            my_yaf_request_abstract = zend_register_internal_class(&ce TSRMLS_CC);            zend_declare_property_null(my_yaf_request_abstract, "action", strlen("action"), ZEND_ACC_PROTECTED TSRMLS_CC);            INIT_CLASS_ENTRY(http_ce, "My_Yaf_Request_Http", my_yaf_request_http_method);            my_yaf_request_http = zend_register_internal_class_ex(&http_ce, my_yaf_request_abstract, "My_Yaf_Request_Abstract" TSRMLS_CC);            my_yaf_request_http->ce_flags |= ZEND_ACC_FINAL_CLASS;            INIT_CLASS_ENTRY(simple_ce, "My_Yaf_Request_Simple", my_yaf_request_simple_method);            my_yaf_request_simple = zend_register_internal_class_ex(&simple_ce, my_yaf_request_abstract, "My_Yaf_Request_Abstract" TSRMLS_CC);            my_yaf_request_simple->ce_flags |= ZEND_ACC_FINAL_CLASS;            return SUCCESS;    }    zend_module_entry myyaf_module_entry = {    #if ZEND_MODULE_API_NO >= 20010901            STANDARD_MODULE_HEADER,    #endif            "myyaf", //这个地方是扩展名称,往往我们会在这个地方使用一个宏。            NULL, /* Functions */            ZEND_MINIT(myyaf), /* MINIT */            NULL, /* MSHUTDOWN */            NULL, /* RINIT */            NULL, /* RSHUTDOWN */            NULL, /* MINFO */    #if ZEND_MODULE_API_NO >= 20010901            "2.1", //这个地方是我们扩展的版本    #endif            STANDARD_MODULE_PROPERTIES    };    ZEND_GET_MODULE(myyaf)    #endifmyyaf.h    //php_myyaf.h    #ifndef MYYAF_H    #define MYYAF_H    //加载config.h,如果配置了的话    #ifdef HAVE_CONFIG_H    #include "config.h"    #endif    //加载php头文件    #include "php.h"    #define phpext_myyaf_ptr &myyaf_module_entry    extern zend_module_entry myyaf_module_entry;     #endif

测试用例

    <?php    $obj_http = new My_Yaf_Request_Http();    $obj_simple = new My_Yaf_Request_Simple();    $obj_http->setActionName("action_http");    var_dump($obj_http->getActionName());    $obj_http->setActionName("action_simple");    var_dump($obj_http->getActionName());    var_dump($obj_http->isCli());    var_dump($obj_simple->isCli());

存疑

  5.4.33的zend引擎只显式提供了zend_register_internal_classzend_register_internal_class_ex分别表示类和子类,并没有提供Abstract类的注册方法。关于如何注册Abstract类,这部分作为后续存疑查找。

0 0
原创粉丝点击