扩展实现php继承
2015-11-20 18:00
621 查看
php代码:
扩展实现:
php_inherit.h:
inherit.c:
测试:
输出:
<?php interface i_myinterface { public function hello(); } class parent_class implements i_myinterface { public function hello() { echo "Good Morning!\n"; } } final class myclass extends parent_class { public function call_hello() { $this->hello(); } } class baby { public $age; public static $area; public function __construct($age, $area) { $this->age = $age; self::$area = $area; var_dump($this->age, self::$area); } } function test_call(){ $obj = new myclass(); $obj->hello(); echo "call test_call"; }
扩展实现:
php_inherit.h:
/* +----------------------------------------------------------------------+ | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: | +----------------------------------------------------------------------+ */ /* $Id$ */ #ifndef PHP_INHERIT_H #define PHP_INHERIT_H extern zend_module_entry inherit_module_entry; #define phpext_inherit_ptr &inherit_module_entry #define PHP_INHERIT_VERSION "0.1.0" /* Replace with version number for your extension */ #ifdef PHP_WIN32 # define PHP_INHERIT_API __declspec(dllexport) #elif defined(__GNUC__) && __GNUC__ >= 4 # define PHP_INHERIT_API __attribute__ ((visibility("default"))) #else # define PHP_INHERIT_API #endif #ifdef ZTS #include "TSRM.h" #endif /* Declare any global variables you may need between the BEGIN and END macros here: 定义所有的全局变量 */ ZEND_BEGIN_MODULE_GLOBALS(inherit) long global_val; char *global_str; unsigned long counter; ZEND_END_MODULE_GLOBALS(inherit) /* Always refer to the globals in your function as INHERIT_G(variable). You are encouraged to rename these macros something shorter, see examples in any other php module directory. */ #ifdef ZTS #define INHERIT_G(v) ZEND_TSRMG(inherit_globals_id, zend_inherit_globals *, v) #ifdef COMPILE_DL_INHERIT ZEND_TSRMLS_CACHE_EXTERN(); #endif #else #define INHERIT_G(v) (inherit_globals.v) #endif #endif /* PHP_INHERIT_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */
inherit.c:
/* +----------------------------------------------------------------------+ | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: | +----------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_inherit.h" #include "Zend/zend_interfaces.h" /* If you declare any globals in php_inherit.h uncomment this: */ ZEND_DECLARE_MODULE_GLOBALS(inherit) /* True global resources - no need for thread safety here */ static int le_inherit; /* {{{ PHP_INI */ /* Remove comments and fill if you need to have entries in php.ini */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("inherit.intval", "42", PHP_INI_PERDIR, OnUpdateLong, global_val, zend_inherit_globals, inherit_globals) STD_PHP_INI_ENTRY("inherit.hello", "hello php", PHP_INI_SYSTEM, OnUpdateString, global_str, zend_inherit_globals, inherit_globals) PHP_INI_ENTRY("inherit.fltval", "0.1", PHP_INI_USER, NULL) PHP_INI_ENTRY("inherit.boolval", "0", PHP_INI_ALL, NULL) PHP_INI_END() //三个zend_class_entry zend_class_entry *i_myinterface_ce, *parent_class_ce, *myclass_ce, *baby_ce; //parent_class的hello方法 i_myinterface_ce接口方法没有方法体 ZEND_METHOD(parent_class, hello){ php_printf("hello parent_class \n"); php_printf("sizeof(area) == %d \n", sizeof("area")); php_printf("strlen(area) == %d \n", strlen("area")); php_printf("PHP_MAJOR_VERSION: %d \n", PHP_MAJOR_VERSION); } //myclass的call_hello方法 ZEND_METHOD(myclass, call_hello){ zval *this_zval; this_zval = getThis(); //这个方法在zend_interfaces.h 中 需要 #include "zend_interfaces.h" zend_call_method_with_0_params(&this_zval, myclass_ce, NULL, "hello", NULL); } ZEND_METHOD(myclass, __construct){ php_printf("myclass __construct \n"); } ZEND_METHOD(baby, __construct){ zval *age, *area; zend_class_entry *self; self = Z_OBJCE_P(getThis()); #if PHP_MAJOR_VERSION == 7 ZEND_PARSE_PARAMETERS_START(2,2) Z_PARAM_ZVAL(age) Z_PARAM_ZVAL_EX(area, 1, 0) //Z_PARAM_OPTIONAL() == '|' ZEND_PARSE_PARAMETERS_END(); #else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &age, &area) == FAILURE){ php_error(E_WARNING, "%s() parameters error", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } #endif zend_update_property(self, getThis(), ZEND_STRL("age"), age TSRMLS_CC); zend_update_static_property(self, ZEND_STRL("area"), area TSRMLS_CC); age = NULL; area = NULL; #if PHP_MAJOR_VERSION == 7 age = zend_read_property(self, getThis(), ZEND_STRL("age"), 0, NULL);// php7 需要一个参数 zval *rv 默认传NULL #else age = zend_read_property(self, getThis(), ZEND_STRL("age"), 0); #endif if (ZVAL_IS_NULL(age)) { php_error(E_WARNING, "age param Is NULL"); RETURN_FALSE; } php_var_dump(&age, 1 TSRMLS_CC); area = zend_read_static_property(self, ZEND_STRL("area"), 0); if (ZVAL_IS_NULL(area)) { zend_error(E_ERROR, "age param Is NULL: %s::$area", self->name); RETURN_FALSE; } php_var_dump(&area, 1 TSRMLS_CC); const char *strval = INI_STR("inherit.hello"); long lval = INI_ORIG_INT("inherit.intval");//获取初始值 double dval = INI_FLT("inherit.fltval");//获取ini变量的值 zend_bool bval = INI_BOOL("inherit.boolval"); php_printf("php_ini_set: inherit.hello: %s, inherit.intval: %d, inherit.fltval: %f, inherit.boolval: %d \n", strval, lval, dval, bval); /* silent参数: 0: 如果属性不存在,则抛出一个notice错误。 1: 如果属性不存在,不报错。 sizeof strlen char str[20] = "0123456789"; strlen(str) == 10 sizeof(str) == 20 char *strs = "0123456789"; sizeof(strs) == 4 pointer sizeof(*strs) == 1 字符串首字符 */ } ZEND_FUNCTION(test_call){ zval * obj; MAKE_STD_ZVAL(obj); object_init_ex(obj, myclass_ce); //如果确认此类没有构造函数就不用调用了。 zend_call_method_with_0_params(&obj, myclass_ce, NULL, "__construct", NULL); zend_call_method_with_0_params(&obj, myclass_ce, NULL, "hello", NULL); php_printf("call test_call \n"); zval_ptr_dtor(&obj); return ; } //各自的zend_function_entry const zend_function_entry i_myinterface_method[] = { ZEND_ABSTRACT_ME(i_myinterface, hello, NULL) ZEND_FE_END }; const zend_function_entry parent_class_method[] = { ZEND_ME(parent_class, hello, NULL, ZEND_ACC_PUBLIC) ZEND_FE_END }; const zend_function_entry myclass_method[] = { ZEND_ME(myclass, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) ZEND_ME(myclass, call_hello, NULL, ZEND_ACC_PUBLIC) ZEND_FE_END }; const zend_function_entry baby_method[] = { ZEND_ME(baby, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) ZEND_FE_END }; PHP_MINIT_FUNCTION(inherit) { REGISTER_INI_ENTRIES();//注册ini变量 //定义常量 /* 等价于define('Author', 'YunDuan'); */ REGISTER_STRINGL_CONSTANT("Author", "YunDuan", sizeof("YunDuan") - 1, CONST_PERSISTENT | CONST_CS); REGISTER_STRINGL_CONSTANT("Version", PHP_INHERIT_VERSION, sizeof(PHP_INHERIT_VERSION) - 1, CONST_PERSISTENT | CONST_CS); zend_class_entry ce, p_ce, i_ce,b_ce; INIT_CLASS_ENTRY(i_ce, "i_myinterface", i_myinterface_method); i_myinterface_ce = zend_register_internal_class(&i_ce TSRMLS_CC); INIT_CLASS_ENTRY(p_ce, "parent_class", parent_class_method); parent_class_ce = zend_register_internal_class(&p_ce TSRMLS_CC); zend_class_implements(parent_class_ce TSRMLS_CC, 1, i_myinterface_ce); //定义子类,使用zend_register_internal_class_ex函数 INIT_CLASS_ENTRY(ce, "myclass", myclass_method); #if PHP_MAJOR_VERSION == 7 myclass_ce = zend_register_internal_class_ex(&ce, parent_class_ce); #else myclass_ce = zend_register_internal_class_ex(&ce,parent_class_ce,"parent_class" TSRMLS_CC); //注意:ZEND_ACC_FINAL是用来修饰方法的,而ZEND_ACC_FINAL_CLASS是用来修饰类的,但php7中已删除 myclass_ce->ce_flags |= ZEND_ACC_FINAL_CLASS; #endif INIT_CLASS_ENTRY(b_ce, "baby", baby_method); baby_ce = zend_register_internal_class(&b_ce TSRMLS_CC); //定义类常量 静态属性 zend_declare_class_constant_stringl(baby_ce, ZEND_STRL("author"), ZEND_STRL("yunduan") TSRMLS_CC); zend_declare_class_constant_stringl(baby_ce, ZEND_STRL("version"), ZEND_STRL(PHP_INHERIT_VERSION) TSRMLS_DC); zend_declare_property_null(baby_ce, ZEND_STRL("area"), ZEND_ACC_PUBLIC|ZEND_ACC_STATIC TSRMLS_CC); zend_declare_property_null(baby_ce, ZEND_STRL("age"), ZEND_ACC_PUBLIC TSRMLS_CC); #ifdef ZEND_ENGINE_3 long TEST = 1; #endif return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(inherit) { UNREGISTER_INI_ENTRIES();//注销ini变量 return SUCCESS; } PHP_RINIT_FUNCTION(inherit) { #if defined(COMPILE_DL_INHERIT) && defined(ZTS) ZEND_TSRMLS_CACHE_UPDATE(); #endif return SUCCESS; } PHP_RSHUTDOWN_FUNCTION(inherit) { return SUCCESS; } PHP_MINFO_FUNCTION(inherit) { php_info_print_table_start(); php_info_print_table_header(2, "inherit support", "enabled"); php_info_print_table_end(); DISPLAY_INI_ENTRIES();//ini param set } const zend_function_entry inherit_functions[] = { PHP_FE(test_call, NULL) PHP_FE_END /* Must be the last line in inherit_functions[] */ }; zend_module_entry inherit_module_entry = { STANDARD_MODULE_HEADER, "inherit", inherit_functions, PHP_MINIT(inherit), PHP_MSHUTDOWN(inherit), PHP_RINIT(inherit), PHP_RSHUTDOWN(inherit), PHP_MINFO(inherit), PHP_INHERIT_VERSION, STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_INHERIT #ifdef ZTS ZEND_TSRMLS_CACHE_DEFINE(); #endif ZEND_GET_MODULE(inherit) #endif
测试:
echo '<pre>'; test_call(); echo "<br>"; echo "author: ",baby::author,"<br>"; echo "version: ",baby::version,"<br>"; $obj = new baby("10", "www"); echo "author: ",Author,"<br>"; echo "version: ",Version,"<br>";
输出:
myclass __construct hello parent_class sizeof(area) == 5 strlen(area) == 4 PHP_MAJOR_VERSION: 5 call test_call author: yunduan version: 0.1.0 string(2) "10" string(2) "wh" php_ini_set: inherit.hello: hello php, inherit.intval: 42, inherit.fltval: 0.100000, inherit.boolval: 0 author: YunDuan version: 0.1.0
相关文章推荐
- 微信开发1.基于Thinkphp3.2网站实现微信接入以及查询tooken值
- laravel5——事件
- PHP接口API文档转换SDK【适配ThinkPHP框架】
- Yii报错:SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in order clause is ambiguous
- YII重点文件
- 【ThinkPHP】SESSION保存机制修改
- MSTP基本配置
- php运行环境学习
- PHP 时间和日期
- PHP中单引号与双引号的区别分析
- PHP连接mysql
- PHP04
- loadrunner中lr_log_message和lr_output_message 的区别
- PHP的三种XML解析器之SimpleXML解析器(三)
- PHP语法(一):基础和变量
- 【ThinkPHP】验证码以及登陆例子
- PHP的三种XML解析器之DOM解析器(二)
- php 原生websocket
- Yii2事务
- ubuntu 配置ftp服务器