From: Gustavo André dos Santos Lopes Date: Sat, 29 Oct 2011 23:17:18 +0000 (+0000) Subject: - Reverted changes that required constructor overrides to invoke the parent X-Git-Tag: php-5.4.0RC1~63 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=32f7337bd4a25e8a2d481fe78437412bb93a2985;p=php - Reverted changes that required constructor overrides to invoke the parent constructor in several SPL classes and applied 5.3 fixes instead. Related bugs: #54384, #55175 and #55300 --- diff --git a/NEWS b/NEWS index 8b0c17a02e..4a6dfec63e 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,11 @@ PHP NEWS . Increased maxium Oracle error message buffer length for new 11.2.0.3 size (Chris Jones) +- SPL extension + . Reverted changes that required constructor overrides to invoke the parent + constructor in several SPL classes and applied 5.3 fixes instead. + Related bugs: #54384, #55175 and #55300. + 20 Oct 2011, PHP 5.4.0 beta2 - General improvements: . Improve the warning message of incompatible arguments. (Laruence) diff --git a/UPGRADING b/UPGRADING index 3b44fbf176..d8ed3190c8 100755 --- a/UPGRADING +++ b/UPGRADING @@ -241,17 +241,6 @@ UPGRADE NOTES - PHP 5.4 stream_truncate that will respond to truncation, e.g. through ftruncate. Strictly speaking, this is an addition to the user-space stream wrapper template, not a change to an actual class. -- Constructors of userspace subclasses of the following SPL classes are now - required to call the parent constructor and not clear any exceptions they - throw (replacing the thrown exception by another one is permitted): - SplFileInfo, DirectoryIterator, FilesystemIterator, GlobIterator, - SplFileObject, SplTempFileObject, RecursiveDirectoryIterator, - IteratorIterator, FilterIterator, RecursiveFilterIterator, ParentIterator, - LimitIterator, CachingIterator, RecursiveCachingIterator, NoRewindIterator, - AppendIterator, InfiniteIterator, RegexIterator, RecursiveRegexIterator, and - RecursiveTreeIterator. - It is no longer possible to defer the parent constructor call until after the - object is constructed. - Classes that implement stream wrappers can define a method called stream_metadata that will be called on touch(), chmod(), chgrp(), chown(). - Arrays cast from SimpleXMLElement now always contain all nodes instead of diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index e875570f59..a39deceb56 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -51,30 +51,14 @@ ZEND_DECLARE_MODULE_GLOBALS(spl) #define SPL_DEFAULT_FILE_EXTENSIONS ".inc,.php" -static void construction_wrapper(INTERNAL_FUNCTION_PARAMETERS); - /* {{{ PHP_GINIT_FUNCTION */ static PHP_GINIT_FUNCTION(spl) { - zend_function *cwf = &spl_globals->constr_wrapper_fun; spl_globals->autoload_extensions = NULL; spl_globals->autoload_extensions_len = 0; spl_globals->autoload_functions = NULL; spl_globals->autoload_running = 0; - spl_globals->validating_fun = NULL; - - cwf->type = ZEND_INTERNAL_FUNCTION; - cwf->common.function_name = "internal_construction_wrapper"; - cwf->common.scope = NULL; /* to be filled w/ object runtime class */ - cwf->common.fn_flags = ZEND_ACC_PRIVATE; - cwf->common.prototype = NULL; - cwf->common.num_args = 0; /* not necessarily true but not enforced */ - cwf->common.required_num_args = 0; - cwf->common.arg_info = NULL; - - cwf->internal_function.handler = construction_wrapper; - cwf->internal_function.module = &spl_module_entry; } /* }}} */ @@ -824,89 +808,6 @@ int spl_build_class_list_string(zval **entry, char **list TSRMLS_DC) /* {{{ */ return ZEND_HASH_APPLY_KEEP; } /* }}} */ -zend_function *php_spl_get_constructor_helper(zval *object, int (*validating_fun)(void *object_data TSRMLS_DC) TSRMLS_DC) /* {{{ */ -{ - if (Z_OBJCE_P(object)->type == ZEND_INTERNAL_CLASS) { - return std_object_handlers.get_constructor(object TSRMLS_CC); - } else { - SPL_G(validating_fun) = validating_fun; - SPL_G(constr_wrapper_fun).common.scope = Z_OBJCE_P(object); - return &SPL_G(constr_wrapper_fun); - } -} -/* }}} */ - -static void construction_wrapper(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ -{ - zval *this = getThis(); - void *object_data; - zend_class_entry *this_ce; - zend_function *zf; - zend_fcall_info fci = {0}; - zend_fcall_info_cache fci_cache = {0}; - zval *retval_ptr = NULL; - - object_data = zend_object_store_get_object(this TSRMLS_CC); - this_ce = Z_OBJCE_P(this); - - /* The call of this internal function did not change the scope because - * zend_do_fcall_common_helper doesn't do that for internal instance - * function calls. So the visibility checks on zend_std_get_constructor - * will still work. Reflection refuses to instantiate classes whose - * constructor is not public so we're OK there too*/ - zf = zend_std_get_constructor(this TSRMLS_CC); - - if (zf == NULL) { - return; - } - - fci.size = sizeof(fci); - fci.function_table = &this_ce->function_table; - /* fci.function_name = ; not necessary */ - /* fci.symbol_table = ; not necessary */ - fci.retval_ptr_ptr = &retval_ptr; - fci.param_count = ZEND_NUM_ARGS(); - if (fci.param_count > 0) { - fci.params = emalloc(fci.param_count * sizeof *fci.params); - if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), fci.params) == FAILURE) { - zend_throw_exception(NULL, "Unexpected error fetching arguments", 0 TSRMLS_CC); - goto cleanup; - } - } - fci.object_ptr = this; - fci.no_separation = 0; - - fci_cache.initialized = 1; - fci_cache.called_scope = this_ce; /* set called scope to class of this */ - /* function->common.scope will replace it, except for - * ZEND_OVERLOADED_FUNCTION, which we won't get */ - fci_cache.calling_scope = EG(scope); - fci_cache.function_handler = zf; - fci_cache.object_ptr = this; - - if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == FAILURE) { - if (!EG(exception)) { - zend_throw_exception(NULL, "Error calling parent constructor", 0 TSRMLS_CC); - } - goto cleanup; - } - if (!EG(exception) && SPL_G(validating_fun)(object_data TSRMLS_CC) == 0) - zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, - "In the constructor of %s, parent::__construct() must be called " - "and its exceptions cannot be cleared", this_ce->name); - -cleanup: - /* no need to cleanup zf, zend_std_get_constructor never allocates a new - * function (so no ZEND_OVERLOADED_FUNCTION or call-via-handlers) */ - if (fci.params != NULL) { - efree(fci.params); - } - if (retval_ptr != NULL) { - zval_ptr_dtor(&retval_ptr); - } -} -/* }}} */ - /* {{{ PHP_MINFO(spl) */ PHP_MINFO_FUNCTION(spl) diff --git a/ext/spl/php_spl.h b/ext/spl/php_spl.h index 7c6e174e97..500f7ef287 100755 --- a/ext/spl/php_spl.h +++ b/ext/spl/php_spl.h @@ -63,15 +63,13 @@ PHP_MINFO_FUNCTION(spl); ZEND_BEGIN_MODULE_GLOBALS(spl) - char * autoload_extensions; - HashTable * autoload_functions; - int autoload_running; - int autoload_extensions_len; - intptr_t hash_mask_handle; - intptr_t hash_mask_handlers; - int hash_mask_init; - zend_function constr_wrapper_fun; - int (*validating_fun)(void *object_data TSRMLS_DC); + char * autoload_extensions; + HashTable * autoload_functions; + int autoload_running; + int autoload_extensions_len; + intptr_t hash_mask_handle; + intptr_t hash_mask_handlers; + int hash_mask_init; ZEND_END_MODULE_GLOBALS(spl) #ifdef ZTS @@ -89,8 +87,6 @@ PHP_FUNCTION(class_uses); PHPAPI void php_spl_object_hash(zval *obj, char* md5str TSRMLS_DC); -zend_function *php_spl_get_constructor_helper(zval *object, int (*validating_fun)(void *object_data TSRMLS_DC) TSRMLS_DC); - #endif /* PHP_SPL_H */ /* diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 0383be28ed..db7d6791df 100755 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -48,8 +48,10 @@ /* declare the class handlers */ static zend_object_handlers spl_filesystem_object_handlers; +/* includes handler to validate object state when retrieving methods */ +static zend_object_handlers spl_filesystem_object_check_handlers; -/* declare the class entry */ +/* decalre the class entry */ PHPAPI zend_class_entry *spl_ce_SplFileInfo; PHPAPI zend_class_entry *spl_ce_DirectoryIterator; PHPAPI zend_class_entry *spl_ce_FilesystemIterator; @@ -142,16 +144,13 @@ static zend_object_value spl_filesystem_object_new_ex(zend_class_entry *class_ty /* intern->type = SPL_FS_INFO; done by set 0 */ intern->file_class = spl_ce_SplFileObject; intern->info_class = spl_ce_SplFileInfo; - if (obj) { - *obj = intern; - } + if (obj) *obj = intern; zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_filesystem_object_free_storage, NULL TSRMLS_CC); retval.handlers = &spl_filesystem_object_handlers; - return retval; } /* }}} */ @@ -164,6 +163,16 @@ static zend_object_value spl_filesystem_object_new(zend_class_entry *class_type } /* }}} */ +/* {{{ spl_filesystem_object_new_ex */ +static zend_object_value spl_filesystem_object_new_check(zend_class_entry *class_type TSRMLS_DC) +{ + zend_object_value ret = spl_filesystem_object_new_ex(class_type, NULL TSRMLS_CC); + ret.handlers = &spl_filesystem_object_check_handlers; + return ret; +} +/* }}} */ + + PHPAPI char* spl_filesystem_object_get_path(spl_filesystem_object *intern, int *len TSRMLS_DC) /* {{{ */ { #ifdef HAVE_GLOB @@ -634,25 +643,17 @@ static HashTable* spl_filesystem_object_get_debug_info(zval *obj, int *is_temp T } /* }}} */ -static int spl_filesystem_object_constructor_validator(void *object_data TSRMLS_DC) /* {{{ */ +zend_function *spl_filesystem_object_get_method_check(zval **object_ptr, char *method, int method_len, const struct _zend_literal *key TSRMLS_DC) /* {{{ */ { - spl_filesystem_object *fsobj = object_data; + spl_filesystem_object *fsobj = zend_object_store_get_object(*object_ptr TSRMLS_CC); - /* check if GlobIterator and Spl[Temp]FileObject had their constructor - * and check if everything went smoothly/there was an exception not cleared - * or if there was an userspace class that did not call the parent - * constructor or cleared its exception */ + if (fsobj->u.dir.entry.d_name[0] == '\0' && fsobj->orig_path == NULL) { + method = "_bad_state_ex"; + method_len = sizeof("_bad_state_ex") - 1; + key = NULL; + } - return (fsobj->u.dir.entry.d_name[0] != '\0' /* GlobIterator */ || - fsobj->_path != NULL /* SplFileInfo */ || - fsobj->orig_path != NULL /* Spl[Temp]FileObject */); -} -/* }}} */ - -static zend_function *spl_filesystem_object_get_constructor(zval *object TSRMLS_DC) /* {{{ */ -{ - return php_spl_get_constructor_helper(object, - spl_filesystem_object_constructor_validator TSRMLS_CC); + return zend_get_std_object_handlers()->get_method(object_ptr, method, method_len, key TSRMLS_CC); } /* }}} */ @@ -1389,6 +1390,15 @@ SPL_METHOD(SplFileInfo, getPathInfo) } /* }}} */ +/* {{{ */ +SPL_METHOD(SplFileInfo, _bad_state_ex) +{ + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, + "The parent constructor was not called: the object is in an " + "invalid state "); +} +/* }}} */ + /* {{{ proto void FilesystemIterator::__construct(string path [, int flags]) Cronstructs a new dir iterator from a path. */ SPL_METHOD(FilesystemIterator, __construct) @@ -1926,6 +1936,7 @@ static const zend_function_entry spl_SplFileInfo_functions[] = { SPL_ME(SplFileInfo, openFile, arginfo_info_openFile, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, setFileClass, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, setInfoClass, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, _bad_state_ex, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) SPL_MA(SplFileInfo, __toString, SplFileInfo, getPathname, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) PHP_FE_END }; @@ -2961,8 +2972,6 @@ PHP_MINIT_FUNCTION(spl_directory) spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone; spl_filesystem_object_handlers.cast_object = spl_filesystem_object_cast; spl_filesystem_object_handlers.get_debug_info = spl_filesystem_object_get_debug_info; - spl_filesystem_object_handlers.get_constructor = spl_filesystem_object_get_constructor; - spl_ce_SplFileInfo->serialize = zend_class_serialize_deny; spl_ce_SplFileInfo->unserialize = zend_class_unserialize_deny; @@ -2971,7 +2980,7 @@ PHP_MINIT_FUNCTION(spl_directory) REGISTER_SPL_IMPLEMENTS(DirectoryIterator, SeekableIterator); spl_ce_DirectoryIterator->get_iterator = spl_filesystem_dir_get_iterator; - + REGISTER_SPL_SUB_CLASS_EX(FilesystemIterator, DirectoryIterator, spl_filesystem_object_new, spl_FilesystemIterator_functions); REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "CURRENT_MODE_MASK", SPL_FILE_DIR_CURRENT_MODE_MASK); @@ -2991,12 +3000,15 @@ PHP_MINIT_FUNCTION(spl_directory) REGISTER_SPL_SUB_CLASS_EX(RecursiveDirectoryIterator, FilesystemIterator, spl_filesystem_object_new, spl_RecursiveDirectoryIterator_functions); REGISTER_SPL_IMPLEMENTS(RecursiveDirectoryIterator, RecursiveIterator); + memcpy(&spl_filesystem_object_check_handlers, &spl_filesystem_object_handlers, sizeof(zend_object_handlers)); + spl_filesystem_object_check_handlers.get_method = spl_filesystem_object_get_method_check; + #ifdef HAVE_GLOB - REGISTER_SPL_SUB_CLASS_EX(GlobIterator, FilesystemIterator, spl_filesystem_object_new, spl_GlobIterator_functions); + REGISTER_SPL_SUB_CLASS_EX(GlobIterator, FilesystemIterator, spl_filesystem_object_new_check, spl_GlobIterator_functions); REGISTER_SPL_IMPLEMENTS(GlobIterator, Countable); #endif - REGISTER_SPL_SUB_CLASS_EX(SplFileObject, SplFileInfo, spl_filesystem_object_new, spl_SplFileObject_functions); + REGISTER_SPL_SUB_CLASS_EX(SplFileObject, SplFileInfo, spl_filesystem_object_new_check, spl_SplFileObject_functions); REGISTER_SPL_IMPLEMENTS(SplFileObject, RecursiveIterator); REGISTER_SPL_IMPLEMENTS(SplFileObject, SeekableIterator); @@ -3005,7 +3017,7 @@ PHP_MINIT_FUNCTION(spl_directory) REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "SKIP_EMPTY", SPL_FILE_OBJECT_SKIP_EMPTY); REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "READ_CSV", SPL_FILE_OBJECT_READ_CSV); - REGISTER_SPL_SUB_CLASS_EX(SplTempFileObject, SplFileObject, spl_filesystem_object_new, spl_SplTempFileObject_functions); + REGISTER_SPL_SUB_CLASS_EX(SplTempFileObject, SplFileObject, spl_filesystem_object_new_check, spl_SplTempFileObject_functions); return SUCCESS; } /* }}} */ diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 28b5866d18..5d0299ed84 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -127,6 +127,17 @@ typedef struct _spl_recursive_it_iterator { static zend_object_handlers spl_handlers_rec_it_it; static zend_object_handlers spl_handlers_dual_it; +#define SPL_FETCH_AND_CHECK_DUAL_IT(var, objzval) \ + do { \ + spl_dual_it_object *it = zend_object_store_get_object((objzval) TSRMLS_CC); \ + if (it->dit_type == DIT_Unknown) { \ + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, \ + "The object is in an invalid state as the parent constructor was not called"); \ + return; \ + } \ + (var) = it; \ + } while (0) + static void spl_recursive_it_dtor(zend_object_iterator *_iter TSRMLS_DC) { spl_recursive_it_iterator *iter = (spl_recursive_it_iterator*)_iter; @@ -409,6 +420,10 @@ static zend_object_iterator *spl_recursive_it_get_iterator(zend_class_entry *ce, } iterator = emalloc(sizeof(spl_recursive_it_iterator)); object = (spl_recursive_it_object*)zend_object_store_get_object(zobject TSRMLS_CC); + if (object->iterators == NULL) { + zend_error(E_ERROR, "The object to be iterated is in an invalid state: " + "the parent constructor has not been called"); + } Z_ADDREF_P(zobject); iterator->intern.data = (void*)object; @@ -851,34 +866,6 @@ static union _zend_function *spl_recursive_it_get_method(zval **object_ptr, char return function_handler; } -static int spl_recursive_it_constructor_validator(void *object_data TSRMLS_DC) /* {{{ */ -{ - spl_recursive_it_object *sobj = object_data; - return (sobj->iterators != NULL); -} -/* }}} */ - -static zend_function *spl_recursive_it_get_constructor(zval *object TSRMLS_DC) /* {{{ */ -{ - return php_spl_get_constructor_helper(object, - spl_recursive_it_constructor_validator TSRMLS_CC); -} -/* }}} */ - -static int spl_dual_it_constructor_validator(void *object_data TSRMLS_DC) /* {{{ */ -{ - spl_dual_it_object *dobj = object_data; - return (dobj->dit_type != DIT_Unknown); -} -/* }}} */ - -static zend_function *spl_dual_it_get_constructor(zval *object TSRMLS_DC) /* {{{ */ -{ - return php_spl_get_constructor_helper(object, - spl_dual_it_constructor_validator TSRMLS_CC); -} -/* }}} */ - /* {{{ spl_RecursiveIteratorIterator_dtor */ static void spl_RecursiveIteratorIterator_dtor(zend_object *_object, zend_object_handle handle TSRMLS_DC) { @@ -1352,6 +1339,15 @@ int spl_dual_it_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) } #endif +#define SPL_CHECK_CTOR(intern, classname) \ + if (intern->dit_type == DIT_Unknown) { \ + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Classes derived from %s must call %s::__construct()", \ + (spl_ce_##classname)->name, (spl_ce_##classname)->name); \ + return; \ + } + +#define APPENDIT_CHECK_CTOR(intern) SPL_CHECK_CTOR(intern, AppendIterator) + static inline int spl_dual_it_fetch(spl_dual_it_object *intern, int check_more TSRMLS_DC); static inline int spl_cit_check_flags(int flags) @@ -1562,12 +1558,12 @@ SPL_METHOD(CallbackFilterIterator, __construct) SPL_METHOD(dual_it, getInnerIterator) { spl_dual_it_object *intern; - - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); if (zend_parse_parameters_none() == FAILURE) { return; } + + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (intern->inner.zobject) { RETVAL_ZVAL(intern->inner.zobject, 1, 0); @@ -1666,13 +1662,13 @@ static inline void spl_dual_it_next(spl_dual_it_object *intern, int do_free TSRM SPL_METHOD(dual_it, rewind) { spl_dual_it_object *intern; - - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); if (zend_parse_parameters_none() == FAILURE) { return; } + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); + spl_dual_it_rewind(intern TSRMLS_CC); spl_dual_it_fetch(intern, 1 TSRMLS_CC); } /* }}} */ @@ -1690,7 +1686,7 @@ SPL_METHOD(dual_it, valid) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_BOOL(intern->current.data); } /* }}} */ @@ -1711,7 +1707,7 @@ SPL_METHOD(dual_it, key) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (intern->current.data) { if (intern->current.key_type == HASH_KEY_IS_STRING) { @@ -1739,7 +1735,7 @@ SPL_METHOD(dual_it, current) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (intern->current.data) { RETVAL_ZVAL(intern->current.data, 1, 0); @@ -1760,7 +1756,7 @@ SPL_METHOD(dual_it, next) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); spl_dual_it_next(intern, 1 TSRMLS_CC); spl_dual_it_fetch(intern, 1 TSRMLS_CC); @@ -1809,7 +1805,7 @@ SPL_METHOD(FilterIterator, rewind) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); spl_filter_it_rewind(getThis(), intern TSRMLS_CC); } /* }}} */ @@ -1823,7 +1819,7 @@ SPL_METHOD(FilterIterator, next) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); spl_filter_it_next(getThis(), intern TSRMLS_CC); } /* }}} */ @@ -1853,7 +1849,7 @@ SPL_METHOD(RecursiveFilterIterator, hasChildren) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval); if (retval) { @@ -1874,7 +1870,7 @@ SPL_METHOD(RecursiveFilterIterator, getChildren) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); if (!EG(exception) && retval) { @@ -1972,7 +1968,7 @@ SPL_METHOD(CallbackFilterIterator, accept) Match (string)current() against regular expression */ SPL_METHOD(RegexIterator, accept) { - spl_dual_it_object *intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_dual_it_object *intern; char *subject, tmp[32], *result; int subject_len, use_copy, count = 0, result_len; zval subject_copy, zcount, *replacement, tmp_replacement; @@ -1981,6 +1977,8 @@ SPL_METHOD(RegexIterator, accept) return; } + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); + if (intern->current.data == NULL) { RETURN_FALSE; } @@ -2095,12 +2093,14 @@ SPL_METHOD(RegexIterator, getRegex) Returns current operation mode */ SPL_METHOD(RegexIterator, getMode) { - spl_dual_it_object *intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_dual_it_object *intern; if (zend_parse_parameters_none() == FAILURE) { return; } + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); + RETURN_LONG(intern->u.regex.mode); } /* }}} */ @@ -2108,7 +2108,7 @@ SPL_METHOD(RegexIterator, getMode) Set new operation mode */ SPL_METHOD(RegexIterator, setMode) { - spl_dual_it_object *intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_dual_it_object *intern; long mode; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &mode) == FAILURE) { @@ -2119,6 +2119,8 @@ SPL_METHOD(RegexIterator, setMode) zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Illegal mode %ld", mode); return;/* NULL */ } + + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); intern->u.regex.mode = mode; } /* }}} */ @@ -2127,12 +2129,14 @@ SPL_METHOD(RegexIterator, setMode) Returns current operation flags */ SPL_METHOD(RegexIterator, getFlags) { - spl_dual_it_object *intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_dual_it_object *intern; if (zend_parse_parameters_none() == FAILURE) { return; } + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); + RETURN_LONG(intern->u.regex.flags); } /* }}} */ @@ -2140,12 +2144,14 @@ SPL_METHOD(RegexIterator, getFlags) Set operation flags */ SPL_METHOD(RegexIterator, setFlags) { - spl_dual_it_object *intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_dual_it_object *intern; long flags; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flags) == FAILURE) { return; } + + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); intern->u.regex.flags = flags; } /* }}} */ @@ -2154,11 +2160,13 @@ SPL_METHOD(RegexIterator, setFlags) Returns current PREG flags (if in use or NULL) */ SPL_METHOD(RegexIterator, getPregFlags) { - spl_dual_it_object *intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_dual_it_object *intern; if (zend_parse_parameters_none() == FAILURE) { return; } + + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (intern->u.regex.use_flags) { RETURN_LONG(intern->u.regex.preg_flags); @@ -2171,12 +2179,14 @@ SPL_METHOD(RegexIterator, getPregFlags) Set PREG flags */ SPL_METHOD(RegexIterator, setPregFlags) { - spl_dual_it_object *intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_dual_it_object *intern; long preg_flags; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &preg_flags) == FAILURE) { return; } + + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); intern->u.regex.preg_flags = preg_flags; intern->u.regex.use_flags = 1; @@ -2200,7 +2210,7 @@ SPL_METHOD(RecursiveRegexIterator, getChildren) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); if (!EG(exception)) { @@ -2473,7 +2483,7 @@ SPL_METHOD(LimitIterator, rewind) { spl_dual_it_object *intern; - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); spl_dual_it_rewind(intern TSRMLS_CC); spl_limit_it_seek(intern, intern->u.limit.offset TSRMLS_CC); } /* }}} */ @@ -2484,7 +2494,7 @@ SPL_METHOD(LimitIterator, valid) { spl_dual_it_object *intern; - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); /* RETURN_BOOL(spl_limit_it_valid(intern TSRMLS_CC) == SUCCESS);*/ RETURN_BOOL((intern->u.limit.count == -1 || intern->current.pos < intern->u.limit.offset + intern->u.limit.count) && intern->current.data); @@ -2496,7 +2506,7 @@ SPL_METHOD(LimitIterator, next) { spl_dual_it_object *intern; - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); spl_dual_it_next(intern, 1 TSRMLS_CC); if (intern->u.limit.count == -1 || intern->current.pos < intern->u.limit.offset + intern->u.limit.count) { @@ -2515,7 +2525,7 @@ SPL_METHOD(LimitIterator, seek) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); spl_limit_it_seek(intern, pos TSRMLS_CC); RETURN_LONG(intern->current.pos); } /* }}} */ @@ -2525,7 +2535,7 @@ SPL_METHOD(LimitIterator, seek) SPL_METHOD(LimitIterator, getPosition) { spl_dual_it_object *intern; - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_LONG(intern->current.pos); } /* }}} */ @@ -2680,7 +2690,7 @@ SPL_METHOD(CachingIterator, rewind) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); spl_caching_it_rewind(intern TSRMLS_CC); } /* }}} */ @@ -2695,7 +2705,7 @@ SPL_METHOD(CachingIterator, valid) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_BOOL(spl_caching_it_valid(intern TSRMLS_CC) == SUCCESS); } /* }}} */ @@ -2710,7 +2720,7 @@ SPL_METHOD(CachingIterator, next) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); spl_caching_it_next(intern TSRMLS_CC); } /* }}} */ @@ -2725,7 +2735,7 @@ SPL_METHOD(CachingIterator, hasNext) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_BOOL(spl_caching_it_has_next(intern TSRMLS_CC) == SUCCESS); } /* }}} */ @@ -2736,7 +2746,7 @@ SPL_METHOD(CachingIterator, __toString) { spl_dual_it_object *intern; - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (!(intern->u.caching.flags & (CIT_CALL_TOSTRING|CIT_TOSTRING_USE_KEY|CIT_TOSTRING_USE_CURRENT|CIT_TOSTRING_USE_INNER))) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s does not fetch string value (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); @@ -2771,7 +2781,7 @@ SPL_METHOD(CachingIterator, offsetSet) uint nKeyLength; zval *value; - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); @@ -2796,7 +2806,7 @@ SPL_METHOD(CachingIterator, offsetGet) uint nKeyLength; zval **value; - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); @@ -2824,7 +2834,7 @@ SPL_METHOD(CachingIterator, offsetUnset) char *arKey; uint nKeyLength; - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); @@ -2847,7 +2857,7 @@ SPL_METHOD(CachingIterator, offsetExists) char *arKey; uint nKeyLength; - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); @@ -2872,7 +2882,7 @@ SPL_METHOD(CachingIterator, getCache) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%v does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); @@ -2893,7 +2903,7 @@ SPL_METHOD(CachingIterator, getFlags) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_LONG(intern->u.caching.flags); } @@ -2906,7 +2916,7 @@ SPL_METHOD(CachingIterator, setFlags) spl_dual_it_object *intern; long flags; - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flags) == FAILURE) { return; @@ -2942,7 +2952,7 @@ SPL_METHOD(CachingIterator, count) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%v does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); @@ -3009,7 +3019,7 @@ SPL_METHOD(RecursiveCachingIterator, hasChildren) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_BOOL(intern->u.caching.zchildren); } /* }}} */ @@ -3024,7 +3034,7 @@ SPL_METHOD(RecursiveCachingIterator, getChildren) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (intern->u.caching.zchildren) { RETURN_ZVAL(intern->u.caching.zchildren, 1, 0); @@ -3094,7 +3104,7 @@ SPL_METHOD(NoRewindIterator, valid) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_BOOL(intern->inner.iterator->funcs->valid(intern->inner.iterator TSRMLS_CC) == SUCCESS); } /* }}} */ @@ -3108,7 +3118,7 @@ SPL_METHOD(NoRewindIterator, key) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (intern->inner.iterator->funcs->get_current_key) { char *str_key; @@ -3140,7 +3150,7 @@ SPL_METHOD(NoRewindIterator, current) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); intern->inner.iterator->funcs->get_current_data(intern->inner.iterator, &data TSRMLS_CC); if (data && *data) { RETURN_ZVAL(*data, 1, 0); @@ -3157,7 +3167,7 @@ SPL_METHOD(NoRewindIterator, next) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); intern->inner.iterator->funcs->move_forward(intern->inner.iterator TSRMLS_CC); } /* }}} */ @@ -3193,7 +3203,7 @@ SPL_METHOD(InfiniteIterator, next) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); spl_dual_it_next(intern, 1 TSRMLS_CC); if (spl_dual_it_valid(intern TSRMLS_CC) == SUCCESS) { @@ -3332,7 +3342,7 @@ SPL_METHOD(AppendIterator, append) spl_dual_it_object *intern; zval *it; - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "O", &it, zend_ce_iterator) == FAILURE) { return; @@ -3360,7 +3370,7 @@ SPL_METHOD(AppendIterator, rewind) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); intern->u.append.iterator->funcs->rewind(intern->u.append.iterator TSRMLS_CC); if (spl_append_it_next_iterator(intern TSRMLS_CC) == SUCCESS) { @@ -3378,7 +3388,7 @@ SPL_METHOD(AppendIterator, valid) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_BOOL(intern->current.data); } /* }}} */ @@ -3393,7 +3403,7 @@ SPL_METHOD(AppendIterator, next) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); spl_append_it_next(intern TSRMLS_CC); } /* }}} */ @@ -3408,8 +3418,9 @@ SPL_METHOD(AppendIterator, getIteratorIndex) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); + + APPENDIT_CHECK_CTOR(intern); spl_array_iterator_key(intern->u.append.zarrayit, return_value TSRMLS_CC); } /* }}} */ @@ -3423,8 +3434,8 @@ SPL_METHOD(AppendIterator, getArrayIterator) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); + RETURN_ZVAL(intern->u.append.zarrayit, 1, 0); } /* }}} */ @@ -3656,13 +3667,11 @@ PHP_MINIT_FUNCTION(spl_iterators) memcpy(&spl_handlers_rec_it_it, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); spl_handlers_rec_it_it.get_method = spl_recursive_it_get_method; spl_handlers_rec_it_it.clone_obj = NULL; - spl_handlers_rec_it_it.get_constructor = spl_recursive_it_get_constructor; memcpy(&spl_handlers_dual_it, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); spl_handlers_dual_it.get_method = spl_dual_it_get_method; /*spl_handlers_dual_it.call_method = spl_dual_it_call_method;*/ spl_handlers_dual_it.clone_obj = NULL; - spl_handlers_dual_it.get_constructor = spl_dual_it_get_constructor; spl_ce_RecursiveIteratorIterator->get_iterator = spl_recursive_it_get_iterator; spl_ce_RecursiveIteratorIterator->iterator_funcs.funcs = &spl_recursive_it_iterator_funcs; diff --git a/ext/spl/tests/CallbackFilterIteratorTest-002.phpt b/ext/spl/tests/CallbackFilterIteratorTest-002.phpt index 4b03d958ba..cbad2e3b9c 100644 --- a/ext/spl/tests/CallbackFilterIteratorTest-002.phpt +++ b/ext/spl/tests/CallbackFilterIteratorTest-002.phpt @@ -41,25 +41,6 @@ try { echo $e->getMessage() . "\n"; } -class Test extends CallbackFilterIterator { - function __construct(){} -} -class Test2 extends RecursiveCallbackFilterIterator { - function __construct(){} -} - -try { - new Test; -} catch(LogicException $e) { - echo $e->getMessage() . "\n"; -} - -try { - new Test2; -} catch(LogicException $e) { - echo $e->getMessage() . "\n"; -} - --EXPECT-- CallbackFilterIterator::__construct() expects exactly 2 parameters, 0 given Argument 1 passed to CallbackFilterIterator::__construct() must implement interface Iterator, null given @@ -67,5 +48,3 @@ CallbackFilterIterator::__construct() expects exactly 2 parameters, 1 given CallbackFilterIterator::__construct() expects parameter 2 to be a valid callback, no array or string given CallbackFilterIterator::__construct() expects parameter 2 to be a valid callback, array must have exactly two members some message -In the constructor of Test, parent::__construct() must be called and its exceptions cannot be cleared -In the constructor of Test2, parent::__construct() must be called and its exceptions cannot be cleared diff --git a/ext/spl/tests/bug41828.phpt b/ext/spl/tests/bug41828.phpt index 41a22c1370..6053e0e446 100644 --- a/ext/spl/tests/bug41828.phpt +++ b/ext/spl/tests/bug41828.phpt @@ -18,8 +18,4 @@ echo $foo->bar(); ==DONE== --EXPECTF-- -Fatal error: Uncaught exception 'LogicException' with message 'In the constructor of foo, parent::__construct() must be called and its exceptions cannot be cleared' in %s:%d -Stack trace: -#0 %s(%d): foo->internal_construction_wrapper('This is bar') -#1 {main} - thrown in %s on line %d +Fatal error: main(): The foo instance wasn't initialized properly in %s on line %d diff --git a/ext/spl/tests/bug54281.phpt b/ext/spl/tests/bug54281.phpt index b1231a8f8b..d42d9e585d 100644 --- a/ext/spl/tests/bug54281.phpt +++ b/ext/spl/tests/bug54281.phpt @@ -12,8 +12,4 @@ foreach($it as $k=>$v) { } ?> --EXPECTF-- -Fatal error: Uncaught exception 'LogicException' with message 'In the constructor of RecursiveArrayIteratorIterator, parent::__construct() must be called and its exceptions cannot be cleared' in %s:%d -Stack trace: -#0 %s(%d): RecursiveArrayIteratorIterator->internal_construction_wrapper(Object(RecursiveArrayIterator), 2) -#1 {main} - thrown in %s on line %d +Fatal error: RecursiveIteratorIterator::rewind(): The RecursiveArrayIteratorIterator instance wasn't initialized properly in %s on line %d diff --git a/ext/spl/tests/bug54384.phpt b/ext/spl/tests/bug54384.phpt index 5f82dccc12..a1ce7edff3 100644 --- a/ext/spl/tests/bug54384.phpt +++ b/ext/spl/tests/bug54384.phpt @@ -131,75 +131,6 @@ $o = new SplTempFileObjectTest; $o->rewind(); } ); - -echo "SplFileInfo... "; -class SplFileInfoTest extends SplFileInfo { - function __construct(){} -} -test ( function() { -$o = new SplFileInfoTest; -$o->getMTime(); -} ); - -echo "DirectoryIterator... "; -class DirectoryIteratortest extends DirectoryIterator { - function __construct(){} -} -test ( function() { -$o = new DirectoryIteratorTest; -foreach ($o as $a) { -echo $a,"\n"; -} -} ); - -echo "DirectoryIterator (exception cleared)... "; -class DirectoryIteratorTest2 extends DirectoryIterator { - function __construct(){ - try { - parent::__construct(); - } catch (Exception $e) { } - } -} -test ( function() { -$o = new DirectoryIteratorTest2; -foreach ($o as $a) { -echo $a,"\n"; -} -} ); - -echo "FileSystemIterator... "; -class FileSystemIteratorTest extends DirectoryIterator { - function __construct(){} -} -test ( function() { -$o = new FileSystemIteratorTest; -foreach ($o as $a) { -echo $a,"\n"; -} -} ); - -echo "RecursiveDirectoryIterator... "; -class RecursiveDirectoryIteratorTest extends RecursiveDirectoryIterator { - function __construct(){} -} -test ( function() { -$o = new RecursiveDirectoryIteratorTest; -foreach ($o as $a) { -echo $a,"\n"; -} -} ); - -echo "RecursiveTreeIterator... "; -class RecursiveTreeIteratorTest extends RecursiveDirectoryIterator { - function __construct(){} -} -test ( function() { -$o = new RecursiveTreeIteratorTest; -foreach ($o as $a) { -echo $a,"\n"; -} -} ); - echo "AppendIterator... "; class AppendIteratorTest extends AppendIterator { function __construct(){} @@ -222,29 +153,6 @@ echo $a,"\n"; } } ); -echo "CallbackFilterIterator... "; -class CallbackFilterIteratorTest extends CallbackFilterIterator { - function __construct(){} -} -test ( function() { -$o = new CallbackFilterIteratorTest; -foreach ($o as $a) { -echo $a,"\n"; -} -} ); - -echo "RecursiveCallbackFilterIterator... "; -class RecursiveCallbackFilterIteratorTest extends RecursiveCallbackFilterIterator { - function __construct(){} -} -test ( function() { -$o = new RecursiveCallbackFilterIteratorTest; -foreach ($o as $a) { -echo $a,"\n"; -} -} ); - - --EXPECT-- IteratorIterator... exception (expected) FilterIterator... exception (expected) @@ -259,13 +167,5 @@ RecursiveRegexIterator... exception (expected) GlobIterator... exception (expected) SplFileObject... exception (expected) SplTempFileObject... exception (expected) -SplFileInfo... exception (expected) -DirectoryIterator... exception (expected) -DirectoryIterator (exception cleared)... exception (expected) -FileSystemIterator... exception (expected) -RecursiveDirectoryIterator... exception (expected) -RecursiveTreeIterator... exception (expected) AppendIterator... exception (expected) InfiniteIterator... exception (expected) -CallbackFilterIterator... exception (expected) -RecursiveCallbackFilterIterator... exception (expected) diff --git a/ext/spl/tests/iterator_031.phpt b/ext/spl/tests/iterator_031.phpt index 90a9710a58..40342f4bb4 100755 --- a/ext/spl/tests/iterator_031.phpt +++ b/ext/spl/tests/iterator_031.phpt @@ -19,19 +19,10 @@ foreach($it as $k=>$v) echo "$k=>$v\n"; } -class MyAppendIterator2 extends AppendIterator -{ - function __construct() - { - echo __METHOD__ . "\n"; - } -} - class MyAppendIterator extends AppendIterator { function __construct() { - parent::__construct(); echo __METHOD__ . "\n"; } @@ -59,23 +50,24 @@ class MyAppendIterator extends AppendIterator } } +$ap = new MyAppendIterator; + try { - $aperr = new MyAppendIterator2; - + $ap->append($it); } -catch(Exception $e) +catch(LogicException $e) { echo $e->getMessage() . "\n"; } -$ap = new MyAppendIterator; +$ap->parent__construct(); try { $ap->parent__construct($it); } -catch(Exception $e) +catch(BadMethodCallException $e) { echo $e->getMessage() . "\n"; } @@ -96,9 +88,9 @@ foreach($ap as $k=>$v) MyArrayIterator::rewind 0=>1 1=>2 -MyAppendIterator2::__construct -In the constructor of MyAppendIterator2, parent::__construct() must be called and its exceptions cannot be cleared MyAppendIterator::__construct +MyAppendIterator::append +The object is in an invalid state as the parent constructor was not called AppendIterator::getIterator() must be called exactly once per instance MyAppendIterator::append MyArrayIterator::rewind