源码阅读:YAF框架系列文章(3) - (yaf_application.c)

@李彪  November 22, 2018

这个文件主要围绕Yaf_Application类的注册,这里,按照倒叙的方式来进行讲解。

一、注册yaf_application类

YAF_STARTUP_FUNCTION(application) {
//定义一个zend_class_entry实例变量
    zend_class_entry ce; 

/* 初始化一个CLASS ENTRY
#define YAF_INIT_CLASS_ENTRY(ce, name, name_ns, methods) \
    if(YAF_G(use_namespace)) { \
        INIT_CLASS_ENTRY(ce, name_ns, methods); \
    } else { \
        INIT_CLASS_ENTRY(ce, name, methods); \
    }
*/
    YAF_INIT_CLASS_ENTRY(ce, "Yaf_Application", "Yaf\\Application", yaf_application_methods);

    // https://src.icorer.com/xref/php-src/Zend/zend_API.c#2752
    //注册一个类到内核类表中
    yaf_application_ce = zend_register_internal_class_ex(&ce, NULL);
    //修改类属性为终极类
    yaf_application_ce->ce_flags |= ZEND_ACC_FINAL;

    //声明一个属性定义,为Protected类型
    zend_declare_property_null(yaf_application_ce,
            ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_CONFIG), ZEND_ACC_PROTECTED);
    zend_declare_property_null(yaf_application_ce,
            ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_DISPATCHER), ZEND_ACC_PROTECTED);
            
    //声明一个NULL元素,为static protected类型
    zend_declare_property_null(yaf_application_ce,
            ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_APP), ZEND_ACC_STATIC | ZEND_ACC_PROTECTED);
    zend_declare_property_null(yaf_application_ce,
            ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_MODULES), ZEND_ACC_PROTECTED);
    //声明一个布尔类型的元素,为protected类型
    zend_declare_property_bool(yaf_application_ce,
            ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_RUN), 0, ZEND_ACC_PROTECTED);
    //声明一个字符串类型的元素 , 为protected类型
    zend_declare_property_string(yaf_application_ce,
            ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_ENV), YAF_G(environ_name), ZEND_ACC_PROTECTED);
    //声明一个长整数类型的元素,为protected类型
    zend_declare_property_long(yaf_application_ce,
            ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_ERRNO), 0, ZEND_ACC_PROTECTED);
    zend_declare_property_string(yaf_application_ce,
            ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_ERRMSG), "", ZEND_ACC_PROTECTED);

    return SUCCESS;
}

二、添加类方法
上面讲解了创建一个类的过程,但是类中还有很多方法,通过yaf_application_methods方法集进行管理,具体对于函数的添加代码如下。

/** {{{ yaf_application_methods

    #define PHP_ME          ZEND_ME
    #define PHP_MN                    ZEND_MN
    #define ZEND_MN(name) zim_##name
    #define ZEND_ME(classname, name, arg_info, flags)    ZEND_FENTRY(name, ZEND_MN(classname##_##name), arg_info, flags)
    #define ZEND_FENTRY(zend_name, name, arg_info, flags)    { #zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags },
    
    #define YAF_ME(c, m, a, f) {m, PHP_MN(c), a, (uint) (sizeof(a)/sizeof(struct _zend_arg_info)-1), f},
*/

zend_function_entry yaf_application_methods[] = {
    PHP_ME(yaf_application, __construct,         yaf_application_construct_arginfo,     ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(yaf_application, run,                 yaf_application_run_arginfo,         ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, execute,             yaf_application_execute_arginfo,     ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, app,                 yaf_application_app_arginfo,         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
    YAF_ME(yaf_application_environ, "environ",   yaf_application_environ_arginfo,     ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, bootstrap,           yaf_application_bootstrap_arginfo,      ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, getConfig,           yaf_application_getconfig_arginfo,     ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, getModules,          yaf_application_getmodule_arginfo,      ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, getDispatcher,       yaf_application_getdispatch_arginfo,    ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, setAppDirectory,     yaf_application_setappdir_arginfo,      ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, getAppDirectory,     yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, getLastErrorNo,      yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, getLastErrorMsg,     yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, clearLastError,      yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
    PHP_ME(yaf_application, __destruct,          NULL,                     ZEND_ACC_PUBLIC | ZEND_ACC_DTOR)
    PHP_ME(yaf_application, __clone,             NULL,                     ZEND_ACC_PRIVATE)
    PHP_ME(yaf_application, __sleep,             NULL,                     ZEND_ACC_PRIVATE)
    PHP_ME(yaf_application, __wakeup,            NULL,                     ZEND_ACC_PRIVATE)
    {NULL, NULL, NULL}
};
/* }}} */

三、为函数方法构建参数信息
因为每个方法函数在创建的时候都会需要参数信息,这种类方法的定义不会像扩展方法那样进行参数解析,但是需要用ZEND_BEGIN_ARG_INFO_EX宏来创建参数信息结构。

/*
    * 这里只做部分讲解

*/

ZEND_BEGIN_ARG_INFO_EX(yaf_application_construct_arginfo, 0, 0, 1)
    ZEND_ARG_INFO(0, config)
    ZEND_ARG_INFO(0, environ)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(yaf_application_app_arginfo, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(yaf_application_execute_arginfo, 0, 0, 2)
    ZEND_ARG_INFO(0, entry)
    ZEND_ARG_INFO(0, ...)
ZEND_END_ARG_INFO()

评论已关闭