php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61442 exception threw in __autoload can not be catched
Submitted: 2012-03-19 19:18 UTC Modified: 2012-09-19 15:40 UTC
Votes:4
Avg. Score:4.5 ± 0.5
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:2 (66.7%)
From: yks-uno at yandex dot ru Assigned: laruence
Status: Closed Package: Scripting Engine problem
PHP Version: 5.3.10 OS: Linux, FreeBSD
Private report: No CVE-ID:
 [2012-03-19 19:18 UTC] yks-uno at yandex dot ru
Description:
------------
If a handler is registered for autoloading (whether via spl_autoload_register() or __autoload()) and it throws an exception when a class is not found, the exception can not be caught as usual if a method of the target class is statically called. Instead, a Fatal Error: Class not found is issued (which is quite what the autoloader is meant to avoid!)
Yet, when, e.g. trying to access a static field of that class, the exceptions get caught correctly.
Tested on several PHP versions (5.3.3 - 5.3.10) on Linux and FreeBSD.

Test script:
---------------
<?
function x($class)
{
    print "xxx\n"; // gets printed
    throw new Exception("Class '{$class}' not found");
}

spl_autoload_register('x');
try {
    $a = A::z(); // FATAL ERROR: class 'A' not found
    // NOTE:
    // $a = A::$z; - will be correctly caught
} catch (Exception $ex) {
    print "{$ex}\n"; // never gets executed
}

Expected result:
----------------
xxx
exception 'Exception' with message 'Class 'A' not found' in <FILE>:5

---
this is what gets output in case the exception is caught


Actual result:
--------------
xxx
Fatal error: Class 'A' not found in <FILE> on line 10


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-09-19 07:15 UTC] yoorick at samovarchik dot info
If you try to use a class constant (e.g. Foo::BAR) of an unexisting class, autoloader will also fail to throw an exception and the script will die with the "class not found" fatal error.
(PHP 5.3.16)
 [2012-09-19 07:44 UTC] laruence@php.net
-Status: Open +Status: Not a bug
 [2012-09-19 07:44 UTC] laruence@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

if you just want to check whether a class exists, use class_exists.

you test script is trying to call a method of a non-exists class,  fatal error is 
reasonable .
 [2012-09-19 08:43 UTC] yks-uno at yandex dot ru
Sorry but you're wrong. Do you understand what the function spl_autoload_register() does? And what the function x() does? The function x() is a handler for loading classes - That is what autoload handler SHOULD DO, it should LOAD classes which are NOT LOADED yet.  And at the moment of loading, you can not tell whether a class EXISTS or not. The test script is calling a method of a class which is NOT LOADED yet.
  It SHOULD report an error if the class being loaded is not found. But it SHOULD NOT DIE on throwing an exception!!! This IS A BUG because an exception is not thrown where it is explicitly written.
You cleverly advise me to use class_exists on a NOT LOADED class, so it just AGAIN forwards an autoload call to the handler (function "x") which eventually DIES.
If you are so clever then just remove the autoload handler from PHP and force use require_once.
Sorry for my being angry, but, damn, it was a HALF-YEAR since bug submitted to invent such a stupid reason that it is not a bug!!!
 [2012-09-19 08:54 UTC] yks-uno at yandex dot ru
And please would you mind to show the exact place in the PHP documentation where it is stated that an autoload handler ALWAYS DIES regardless of exceptions or substituting another class if it does not find the class it is trying to load? 
Or there is "no information available, might only be in SVN" ???
 [2012-09-19 10:03 UTC] laruence@php.net
http://us.php.net/autoload

"Note:

Prior to 5.3.0, exceptions thrown in the __autoload function could not be caught 
in the catch block and would result in a fatal error. From 5.3.0+ exceptions 
thrown in the __autoload function can be caught in the catch block, with 1 
provision. If throwing a custom exception, then the custom exception class must 
be available. The __autoload function may be used recursively to autoload the 
custom exception class."
 [2012-09-19 10:09 UTC] laruence@php.net
and the 5.3.0+ seems should be 5.3+ (I mean 5.4 works fine).
 [2012-09-19 10:33 UTC] laruence@php.net
hmm, seems I thought wrongly,

try {
   new AAAA();
} catch () {
}

can be catched in 5.3

but 
try {
  AAA:xxx();
} 

can not be catched in 5.3, but can be catched in 5.4.
 [2012-09-19 10:33 UTC] laruence@php.net
-Status: Not a bug +Status: Re-Opened
 [2012-09-19 10:37 UTC] yks-uno at yandex dot ru
That is what it was all about.
Again sorry for resentment, thanks for clearing things up.
 [2012-09-19 11:28 UTC] laruence@php.net
-Summary: SPL autoload issues Fatal Error if a handler throws exception +Summary: exception threw in __autoload can not be catched
 [2012-09-19 11:41 UTC] laruence@php.net
-: yks-uno at yandex dot ru +: laruence@php.net -Status: Re-Opened +Status: Closed
 [2012-09-19 11:41 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=fd0b3ea663431b7adaedde11668fbc0b6ba07494
Log: Fixed bug #61442 (exception threw in __autoload can not be catched)
 [2012-09-19 11:42 UTC] laruence@php.net
-Package: SPL related +Package: Scripting Engine problem -Assigned To: +Assigned To: laruence
 [2012-09-19 11:51 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=fd0b3ea663431b7adaedde11668fbc0b6ba07494
Log: Fixed bug #61442 (exception threw in __autoload can not be catched)
 [2012-09-19 11:52 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=fd0b3ea663431b7adaedde11668fbc0b6ba07494
Log: Fixed bug #61442 (exception threw in __autoload can not be catched)
 [2012-09-19 14:36 UTC] nikic@php.net
@laruence: Shouldn't the ZEND_VM_CONTINUE() rather be a HANDLE_EXCEPTION()?
 [2012-09-19 15:40 UTC] laruence@php.net
@nikic, there is no such macro in 5.3
 [2012-09-19 16:04 UTC] nikic@php.net
@laruence: Ah, sorry, I missed that this was a 5.3-only bug.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Mon Apr 21 10:02:10 2014 UTC