扩展实现php继承

来源:互联网 发布:mac itunes 资料库 编辑:程序博客网 时间:2024/06/04 22:33
php代码:
<?phpinterface 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_Hextern 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 BEGINand 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_INHERITZEND_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_entryzend_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;        }#endifzend_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 == 7age = zend_read_property(self, getThis(), ZEND_STRL("age"), 0, NULL);// php7 需要一个参数 zval *rv 默认传NULL#elseage = zend_read_property(self, getThis(), ZEND_STRL("age"), 0);#endifif (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 strlenchar str[20] = "0123456789";strlen(str) == 10sizeof(str) == 20char *strs = "0123456789";sizeof(strs) == 4 pointersizeof(*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_entryconst 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 == 7myclass_ce = zend_register_internal_class_ex(&ce, parent_class_ce);#elsemyclass_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;#endifINIT_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_3long TEST = 1;#endifreturn 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();#endifreturn 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 ZTSZEND_TSRMLS_CACHE_DEFINE();#endifZEND_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 __constructhello parent_classsizeof(area) == 5strlen(area) == 4PHP_MAJOR_VERSION: 5call test_callauthor:  yunduanversion: 0.1.0string(2) "10"string(2) "wh"php_ini_set: inherit.hello: hello php, inherit.intval: 42, inherit.fltval: 0.100000, inherit.boolval: 0author:  YunDuanversion: 0.1.0




0 0
原创粉丝点击