]> granicus.if.org Git - php/commitdiff
- MFH Allow multiple exceptions in spl's autoload
authorMarcus Boerger <helly@php.net>
Sat, 12 Jul 2008 14:58:41 +0000 (14:58 +0000)
committerMarcus Boerger <helly@php.net>
Sat, 12 Jul 2008 14:58:41 +0000 (14:58 +0000)
ext/spl/php_spl.c
ext/spl/tests/spl_autoload_012.phpt [new file with mode: 0755]

index 40612c126cd43824e946a95239898e77cc4aa9db..a8404314c1f65c11e5400596311329ac4f47673b 100755 (executable)
@@ -379,14 +379,22 @@ PHP_FUNCTION(spl_autoload_call)
 
        if (SPL_G(autoload_functions)) {
                int l_autoload_running = SPL_G(autoload_running);
+               zval *exception = NULL;
                SPL_G(autoload_running) = 1;
                class_name_len = Z_STRLEN_P(class_name);
                lc_name = zend_str_tolower_dup(Z_STRVAL_P(class_name), class_name_len);
                zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &function_pos);
-               while(zend_hash_has_more_elements_ex(SPL_G(autoload_functions), &function_pos) == SUCCESS && !EG(exception)) {
+               while(zend_hash_has_more_elements_ex(SPL_G(autoload_functions), &function_pos) == SUCCESS) {
                        zend_hash_get_current_key_ex(SPL_G(autoload_functions), &func_name, &func_name_len, &dummy, 0, &function_pos);
                        zend_hash_get_current_data_ex(SPL_G(autoload_functions), (void **) &alfi, &function_pos);
                        zend_call_method(alfi->obj ? &alfi->obj : NULL, alfi->ce, &alfi->func_ptr, func_name, func_name_len, &retval, 1, class_name, NULL TSRMLS_CC);
+                       if (EG(exception)) {
+                               if (exception) {
+                                       zend_update_property(zend_exception_get_default(TSRMLS_C), EG(exception), "previous", sizeof("previous")-1, exception TSRMLS_CC);
+                               }
+                               exception = EG(exception);
+                               EG(exception) = NULL;
+                       }
                        if (retval) {
                                zval_ptr_dtor(&retval);
                        }
@@ -395,6 +403,7 @@ PHP_FUNCTION(spl_autoload_call)
                        }
                        zend_hash_move_forward_ex(SPL_G(autoload_functions), &function_pos);
                }
+               EG(exception) = exception;
                efree(lc_name);
                SPL_G(autoload_running) = l_autoload_running;
        } else {
diff --git a/ext/spl/tests/spl_autoload_012.phpt b/ext/spl/tests/spl_autoload_012.phpt
new file mode 100755 (executable)
index 0000000..b3e869a
--- /dev/null
@@ -0,0 +1,42 @@
+--TEST--
+SPL: spl_autoload() capturing multiple Exceptions in __autoload
+--FILE--
+<?php
+
+function autoload_first($name)
+{
+  echo __METHOD__ . "\n";
+  throw new Exception('first');
+}
+
+function autoload_second($name)
+{
+  echo __METHOD__ . "\n";
+  throw new Exception('second');
+}
+
+spl_autoload_register('autoload_first');
+spl_autoload_register('autoload_second');
+
+class_exists('ThisClassDoesNotExist');
+
+?>
+===DONE===
+--EXPECTF--
+autoload_first
+autoload_second
+
+Fatal error: Uncaught exception 'Exception' with message 'first' in %sspl_autoload_012.php:%d
+Stack trace:
+#0 [internal function]: autoload_first('ThisClassDoesNo...')
+#1 [internal function]: spl_autoload_call('ThisClassDoesNo...')
+#2 %sspl_autoload_012.php(%d): class_exists('ThisClassDoesNo...')
+#3 {main}
+
+Next exception 'Exception' with message 'second' in %sspl_autoload_012.php:%d
+Stack trace:
+#0 [internal function]: autoload_second('ThisClassDoesNo...')
+#1 [internal function]: spl_autoload_call('ThisClassDoesNo...')
+#2 %sspl_autoload_012.php(%d): class_exists('ThisClassDoesNo...')
+#3 {main}
+  thrown in %sspl_autoload_012.php on line %d
\ No newline at end of file