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

Posted by LB on Thu, Nov 22, 2018

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

一、注册yaf_application类

 1YAF_STARTUP_FUNCTION(application) {
 2//定义一个zend_class_entry实例变量
 3	zend_class_entry ce; 
 4
 5/* 初始化一个CLASS ENTRY
 6#define YAF_INIT_CLASS_ENTRY(ce, name, name_ns, methods) \
 7	if(YAF_G(use_namespace)) { \
 8		INIT_CLASS_ENTRY(ce, name_ns, methods); \
 9	} else { \
10		INIT_CLASS_ENTRY(ce, name, methods); \
11	}
12*/
13	YAF_INIT_CLASS_ENTRY(ce, "Yaf_Application", "Yaf\\Application", yaf_application_methods);
14
15	// https://src.icorer.com/xref/php-src/Zend/zend_API.c#2752
16	//注册一个类到内核类表中
17	yaf_application_ce = zend_register_internal_class_ex(&ce, NULL);
18	//修改类属性为终极类
19	yaf_application_ce->ce_flags |= ZEND_ACC_FINAL;
20
21	//声明一个属性定义,为Protected类型
22	zend_declare_property_null(yaf_application_ce,
23			ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_CONFIG), ZEND_ACC_PROTECTED);
24	zend_declare_property_null(yaf_application_ce,
25			ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_DISPATCHER), ZEND_ACC_PROTECTED);
26			
27	//声明一个NULL元素,为static protected类型
28	zend_declare_property_null(yaf_application_ce,
29			ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_APP), ZEND_ACC_STATIC | ZEND_ACC_PROTECTED);
30	zend_declare_property_null(yaf_application_ce,
31			ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_MODULES), ZEND_ACC_PROTECTED);
32	//声明一个布尔类型的元素,为protected类型
33	zend_declare_property_bool(yaf_application_ce,
34			ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_RUN), 0, ZEND_ACC_PROTECTED);
35	//声明一个字符串类型的元素 , 为protected类型
36	zend_declare_property_string(yaf_application_ce,
37			ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_ENV), YAF_G(environ_name), ZEND_ACC_PROTECTED);
38	//声明一个长整数类型的元素,为protected类型
39	zend_declare_property_long(yaf_application_ce,
40			ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_ERRNO), 0, ZEND_ACC_PROTECTED);
41	zend_declare_property_string(yaf_application_ce,
42			ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_ERRMSG), "", ZEND_ACC_PROTECTED);
43
44	return SUCCESS;
45}

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

 1/** {{{ yaf_application_methods
 2
 3	#define PHP_ME          ZEND_ME
 4	#define PHP_MN					ZEND_MN
 5	#define ZEND_MN(name) zim_##name
 6	#define ZEND_ME(classname, name, arg_info, flags)	ZEND_FENTRY(name, ZEND_MN(classname##_##name), arg_info, flags)
 7	#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 },
 8	
 9	#define YAF_ME(c, m, a, f) {m, PHP_MN(c), a, (uint) (sizeof(a)/sizeof(struct _zend_arg_info)-1), f},
10*/
11
12zend_function_entry yaf_application_methods[] = {
13	PHP_ME(yaf_application, __construct,         yaf_application_construct_arginfo,     ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
14	PHP_ME(yaf_application, run,                 yaf_application_run_arginfo,         ZEND_ACC_PUBLIC)
15	PHP_ME(yaf_application, execute,             yaf_application_execute_arginfo,     ZEND_ACC_PUBLIC)
16	PHP_ME(yaf_application, app,                 yaf_application_app_arginfo,         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
17	YAF_ME(yaf_application_environ, "environ",   yaf_application_environ_arginfo,     ZEND_ACC_PUBLIC)
18	PHP_ME(yaf_application, bootstrap,           yaf_application_bootstrap_arginfo,      ZEND_ACC_PUBLIC)
19	PHP_ME(yaf_application, getConfig,           yaf_application_getconfig_arginfo,     ZEND_ACC_PUBLIC)
20	PHP_ME(yaf_application, getModules,          yaf_application_getmodule_arginfo,      ZEND_ACC_PUBLIC)
21	PHP_ME(yaf_application, getDispatcher,       yaf_application_getdispatch_arginfo,    ZEND_ACC_PUBLIC)
22	PHP_ME(yaf_application, setAppDirectory,     yaf_application_setappdir_arginfo,      ZEND_ACC_PUBLIC)
23	PHP_ME(yaf_application, getAppDirectory,     yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
24	PHP_ME(yaf_application, getLastErrorNo,      yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
25	PHP_ME(yaf_application, getLastErrorMsg,     yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
26	PHP_ME(yaf_application, clearLastError,      yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
27	PHP_ME(yaf_application, __destruct,          NULL,                     ZEND_ACC_PUBLIC | ZEND_ACC_DTOR)
28	PHP_ME(yaf_application, __clone,             NULL,                     ZEND_ACC_PRIVATE)
29	PHP_ME(yaf_application, __sleep,             NULL,                     ZEND_ACC_PRIVATE)
30	PHP_ME(yaf_application, __wakeup,            NULL,                     ZEND_ACC_PRIVATE)
31	{NULL, NULL, NULL}
32};
33/* }}} */

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

 1/*
 2	* 这里只做部分讲解
 3
 4*/
 5
 6ZEND_BEGIN_ARG_INFO_EX(yaf_application_construct_arginfo, 0, 0, 1)
 7	ZEND_ARG_INFO(0, config)
 8	ZEND_ARG_INFO(0, environ)
 9ZEND_END_ARG_INFO()
10
11ZEND_BEGIN_ARG_INFO_EX(yaf_application_app_arginfo, 0, 0, 0)
12ZEND_END_ARG_INFO()
13
14ZEND_BEGIN_ARG_INFO_EX(yaf_application_execute_arginfo, 0, 0, 2)
15	ZEND_ARG_INFO(0, entry)
16	ZEND_ARG_INFO(0, ...)
17ZEND_END_ARG_INFO()