? .cproject ? .project ? Zend ? lsb.forward_static_call.patch ? lsb.new-keyword.patch ? lsb.parent-forwarding.patch ? pear/scripts Index: ext/standard/basic_functions.c =================================================================== RCS file: /repository/php-src/ext/standard/basic_functions.c,v retrieving revision 1.725.2.31.2.64.2.14 diff -u -r1.725.2.31.2.64.2.14 basic_functions.c --- ext/standard/basic_functions.c 21 Nov 2007 10:24:21 -0000 1.725.2.31.2.64.2.14 +++ ext/standard/basic_functions.c 26 Nov 2007 04:01:48 -0000 @@ -810,6 +810,19 @@ ZEND_END_ARG_INFO() static +ZEND_BEGIN_ARG_INFO_EX(arginfo_forward_static_call, 0, 0, 1) + ZEND_ARG_INFO(0, method_name) + ZEND_ARG_INFO(0, parmeter) + ZEND_ARG_INFO(0, ...) +ZEND_END_ARG_INFO() +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_forward_static_call_array, 0, 0, 2) + ZEND_ARG_INFO(0, method_name) + ZEND_ARG_INFO(0, parameters) /* ARRAY_INFO(0, parameters, 1) */ +ZEND_END_ARG_INFO() + + +static ZEND_BEGIN_ARG_INFO(arginfo_register_shutdown_function, 0) ZEND_ARG_INFO(0, function_name) ZEND_END_ARG_INFO() @@ -3357,6 +3370,8 @@ PHP_FE(call_user_func_array, arginfo_call_user_func_array) PHP_DEP_FE(call_user_method, arginfo_call_user_method) PHP_DEP_FE(call_user_method_array, arginfo_call_user_method_array) + PHP_FE(forward_static_call, arginfo_forward_static_call) + PHP_FE(forward_static_call_array, arginfo_forward_static_call_array) PHP_FE(serialize, arginfo_serialize) PHP_FE(unserialize, arginfo_unserialize) @@ -5214,6 +5229,126 @@ } /* }}} */ +/* {{{ proto mixed forward_static_call(string method_name [, mixed parmeter] [, mixed ...]) + Call a method on the current scope parent's class using the current class as the caller */ +PHP_FUNCTION(forward_static_call) +{ + char *method_name; + int method_name_len; + zval ***params = NULL; + zend_uint param_count = 0; + + zval *retval_ptr = NULL; + zend_fcall_info fci; + zend_fcall_info_cache fci_cache; + zval *callable; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s*", &method_name, &method_name_len, ¶ms, ¶m_count) == FAILURE) { + return; + } + + if (!EG(active_op_array)->scope) { + zend_error(E_ERROR, "Cannot call forward_static_call() when no class scope is active"); + } else if (!EG(active_op_array)->scope->parent) { + zend_error(E_ERROR, "Cannot call forward_static_call() when current class scope has no parent"); + } + + /** + * Setup the callable zval + */ + ALLOC_INIT_ZVAL(callable); + array_init(callable); + add_next_index_string(callable, "parent", 1); + add_next_index_stringl(callable, method_name, method_name_len, 1); + + /** + * Setup the fcall_info and fcall_info_cache + */ + if (zend_fcall_info_init(callable, &fci, &fci_cache, NULL) == SUCCESS) { + fci.params = params; + fci.param_count = param_count; + fci_cache.calling_scope = EG(called_scope); + + /** + * Point the function return to the called function and call it + */ + fci.retval_ptr_ptr = &retval_ptr; + + if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && fci.retval_ptr_ptr && *fci.retval_ptr_ptr) { + COPY_PZVAL_TO_ZVAL(*return_value, *fci.retval_ptr_ptr); + } + } else { + zend_error(E_ERROR, "forward_static_call() expects parameter 1 to be a static method found in class '%s', '%s' given", EG(active_op_array)->scope->parent->name, method_name); + } + /** + * Cleanup + */ + zval_ptr_dtor(&callable); + if (fci.params) { + efree(fci.params); + } +} +/* }}} */ + +/* {{{ proto mixed call_user_func_array(string method_name, array parameters) + Call a user function which is the first parameter with the arguments contained in array */ +PHP_FUNCTION(forward_static_call_array) +{ + char *method_name; + int method_name_len; + + zval *params, *retval_ptr = NULL; + + zend_fcall_info fci; + zend_fcall_info_cache fci_cache; + zval *callable; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa/", &method_name, &method_name_len, ¶ms) == FAILURE) { + return; + } + + if (!EG(active_op_array)->scope) { + zend_error(E_ERROR, "Cannot call forward_static_call_array() when no class scope is active"); + } else if (!EG(active_op_array)->scope->parent) { + zend_error(E_ERROR, "Cannot call forward_static_call_array() when current class scope has no parent"); + } + + + /** + * Setup the callable zval + */ + ALLOC_INIT_ZVAL(callable); + array_init(callable); + add_next_index_string(callable, "parent", 1); + add_next_index_stringl(callable, method_name, method_name_len, 1); + + /** + * Setup the fcall_info and fcall_info_cache + */ + if (zend_fcall_info_init(callable, &fci, &fci_cache, NULL) == SUCCESS) { + fci_cache.calling_scope = EG(called_scope); + zend_fcall_info_args(&fci, params TSRMLS_CC); + + /** + * Point the function return to the called function and call it + */ + fci.retval_ptr_ptr = &retval_ptr; + + if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && fci.retval_ptr_ptr && *fci.retval_ptr_ptr) { + COPY_PZVAL_TO_ZVAL(*return_value, *fci.retval_ptr_ptr); + } + } else { + zend_error(E_ERROR, "forward_static_call_array() expects parameter 1 to be a static method found in class '%s', '%s' given", EG(active_op_array)->scope->parent->name, method_name); + } + + /** + * Cleanup + */ + zval_ptr_dtor(&callable); + zend_fcall_info_args_clear(&fci, 1); +} +/* }}} */ + void user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_entry) /* {{{ */ { int i; Index: ext/standard/basic_functions.h =================================================================== RCS file: /repository/php-src/ext/standard/basic_functions.h,v retrieving revision 1.139.2.4.2.6.2.3 diff -u -r1.139.2.4.2.6.2.3 basic_functions.h --- ext/standard/basic_functions.h 2 Nov 2007 19:40:39 -0000 1.139.2.4.2.6.2.3 +++ ext/standard/basic_functions.h 26 Nov 2007 04:01:48 -0000 @@ -84,6 +84,8 @@ PHP_FUNCTION(call_user_func_array); PHP_FUNCTION(call_user_method); PHP_FUNCTION(call_user_method_array); +PHP_FUNCTION(forward_static_call); +PHP_FUNCTION(forward_static_call_array); PHP_FUNCTION(register_shutdown_function); PHP_FUNCTION(highlight_file);