From: Etienne Kneuss Date: Sun, 25 May 2008 12:17:27 +0000 (+0000) Subject: Add a prepend param to spl_autoload_register X-Git-Tag: BEFORE_HEAD_NS_CHANGE~1674 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=be6d55935cce39c8d316f1b95ca70a17082598e8;p=php Add a prepend param to spl_autoload_register --- diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index 8212f5f84f..485c0ba2b5 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -393,7 +393,14 @@ PHP_FUNCTION(spl_autoload_call) zval_ptr_dtor(&zclass_name); } /* }}} */ -/* {{{ proto bool spl_autoload_register([mixed autoload_function = "spl_autoload" [, throw = true]]) U +#define HT_MOVE_TAIL_TO_HEAD(ht) \ + (ht)->pListTail->pListNext = (ht)->pListHead; \ + (ht)->pListHead = (ht)->pListTail; \ + (ht)->pListTail = (ht)->pListHead->pListLast; \ + (ht)->pListTail->pListNext = NULL; \ + (ht)->pListHead->pListLast = NULL; + +/* {{{ proto bool spl_autoload_register([mixed autoload_function = "spl_autoload" [, throw = true [, prepend = false]]]) U Register given function as __autoload() implementation */ PHP_FUNCTION(spl_autoload_register) { @@ -401,11 +408,12 @@ PHP_FUNCTION(spl_autoload_register) zval zfunc_name, ztmp; zval *zcallable = NULL; zend_bool do_throw = 1; + zend_bool prepend = 0; zend_function *spl_func_ptr; autoload_func_info alfi; zval **obj_ptr; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "|zb", &zcallable, &do_throw) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "|zbb", &zcallable, &do_throw, &prepend) == FAILURE) { return; } @@ -517,9 +525,17 @@ PHP_FUNCTION(spl_autoload_register) spl_alfi.obj = NULL; spl_alfi.ce = NULL; zend_hash_add(SPL_G(autoload_functions), "spl_autoload", sizeof("spl_autoload"), &spl_alfi, sizeof(autoload_func_info), NULL); + if (prepend && SPL_G(autoload_functions)->nNumOfElements > 1) { + /* Move the newly created element to the head of the hashtable */ + HT_MOVE_TAIL_TO_HEAD(SPL_G(autoload_functions)); + } } zend_u_hash_add(SPL_G(autoload_functions), Z_TYPE(zfunc_name), Z_UNIVAL(zfunc_name), Z_UNILEN(zfunc_name)+1, &alfi, sizeof(autoload_func_info), NULL); + if (prepend && SPL_G(autoload_functions)->nNumOfElements > 1) { + /* Move the newly created element to the head of the hashtable */ + HT_MOVE_TAIL_TO_HEAD(SPL_G(autoload_functions)); + } skip: zval_dtor(&zfunc_name); } diff --git a/ext/spl/tests/spl_autoload_010.phpt b/ext/spl/tests/spl_autoload_010.phpt new file mode 100644 index 0000000000..cd70bdccf0 --- /dev/null +++ b/ext/spl/tests/spl_autoload_010.phpt @@ -0,0 +1,30 @@ +--TEST-- +SPL: spl_autoload() and prepend +--INI-- +include_path=. +--FILE-- + $name\n"; +} +function autoloadB($name) { + echo "B -> $name\n"; +} +function autoloadC($name) { + echo "C -> $name\n"; + class C{} +} + +spl_autoload_register('autoloadA'); +spl_autoload_register('autoloadB', true, true); +spl_autoload_register('autoloadC'); + +new C; +?> +===DONE=== + +--EXPECTF-- +B -> C +A -> C +C -> C +===DONE=== diff --git a/ext/spl/tests/spl_autoload_011.phpt b/ext/spl/tests/spl_autoload_011.phpt new file mode 100644 index 0000000000..5a992550e5 --- /dev/null +++ b/ext/spl/tests/spl_autoload_011.phpt @@ -0,0 +1,31 @@ +--TEST-- +SPL: spl_autoload() and object freed +--INI-- +include_path=. +--FILE-- +var."\n"; + } + public function __destruct() { + echo "__destruct__\n"; + } +} + +$a = new A; +$a->var = 2; + +spl_autoload_register(array($a, 'autoload')); +unset($a); + +var_dump(class_exists("C", true)); +?> +===DONE=== + +--EXPECTF-- +var:2 +bool(false) +===DONE=== +__destruct__