php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52412 __autoload fails to throw exception when calling a static method on the class
Submitted: 2010-07-23 09:34 UTC Modified: 2011-02-16 11:24 UTC
Votes:28
Avg. Score:4.6 ± 0.7
Reproduced:28 of 28 (100.0%)
Same Version:18 (64.3%)
Same OS:7 (25.0%)
From: madboyka at yahoo dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.3.3 OS: *
Private report: No CVE-ID: None
 [2010-07-23 09:34 UTC] madboyka at yahoo dot com
Description:
------------
I've tried to do the following:

1. Wrote and autoload method, that throws an exception.
3. Made a static call on a non-existing class within a try block.

Tried this on windows 7 / Apache 2.2 / PHP 5.3.3.

Test script:
---------------
<?php

function __autoload($class_name) {
	throw new Exception($class_name);
}

try {
	Application::start();
        // new Application(); works fine
} catch (Exception $ex) {
	var_dump($ex);
}


Expected result:
----------------
The script should var_dump() an exception with the Message 'Application' as it does when instantiating a class.

Actual result:
--------------
The script dies with Fatal error: Class 'Application' not found.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-09-03 03:26 UTC] php dot net at phrozenbyte dot de
Same on Ubuntu 10.04 / Apache 2.2 and CLI mode

Test script:
---------------
<?php
spl_autoload_register(
	function($autoload) {
		throw new Exception();
	}
);
try {
	Foo::bar();
} catch(Exception $e) {
	echo "Exception caught\n";
}
?>

Expected result:
----------------
Exception caught

Actual result:
--------------
Fatal error: Class 'Foo' not found in /home/daniel/www/other/php-bug.php on line 0
 [2010-09-25 23:39 UTC] alex dot offshore at gmail dot com
Temporary solution.
Caveats and notices:
- The class actually WILL BE DEFINED ANYWAY;
- 'eval' usage;
- __callStatic used to avoid "method not found" error.

<?php
function __autoload($className)
{
  echo "Want to load $className.\n";
  
  // assuming we can not load class
  // error handling code
  {
    eval('class ' . $className . ' { static function __callStatic($n, $a) { return false; } }');
    throw new Exception("Unable to load $className.");
  }
}

try
{
  //new MissingClass(); // works as expected
  MissingClass::someFunction();
}
catch (Exception $e)
{
  echo 'CAUGHT: ' . $e->getMessage(), "\n";
}
 [2011-02-16 08:05 UTC] michael at squiloople dot com
There's a slight hack of a solution tested using PHP 5.3.5 and Windows Vista: 
use a variable as the class name:

function __autoload($class)
{

  if (!include $class . '.php')
  {
    throw new Exception('Cannot autoload ' . $class);
  }

}

$class = 'Application';

try
{
  $class::start();
}

catch (Exception $e)
{
  echo $e->getMessage();
}

// Outputs the exception as expected.
 [2011-02-16 11:24 UTC] derick@php.net
-Status: Open +Status: Bogus -Operating System: Windows +Operating System: *
 [2011-02-16 11:24 UTC] derick@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

FWIW, this is "expected". The __autoload() method is the last line of defense for PHP to find a class definition. If it can't find it, PHP bails out with a fatal error. If you throw an exception, you basically abort this final chance, and thus gives PHP you that fatal "can not find class" error. However, you can catch the exception in the __autoload() method,
 [2011-02-16 15:31 UTC] madboyka at yahoo dot com
To: derick@php.net
I don't think you've read the documentation on autoloading yourself:
http://www.php.net/manual/en/language.oop5.autoload.php

The first note states that since PHP 5.3, you may throw an exception from the autoload function (even if the class can be loaded) and catch that exception without a problem. Examples #3 and #4 in the documentation entry demonstrate this. This works when the autoload function gets invoked when instantiating a class, but doesn't when you make a static call on it. This behavior is not consistent.
Also, take a look at michael@...'s workaround, which unexpectedly works great. And don't tell me that PHP behaves as "expected".

I understand, that this is not a major bug, we all can live without a fix, but at least mark it as to be fixed in the far future.
 [2011-02-19 23:06 UTC] michael at squiloople dot com
Here's a request to re-open the bug, for it is indeed a bug: exceptions can be 
thrown and caught if the method called is _not_ static, as documented, but cannot 
be thrown and caught if the method _is_ static (and where the class name is not a 
variable), which is both inconsistent and against the documentation. It is 
_unexpected_ behaviour.
 [2011-02-21 19:35 UTC] php dot net at phrozenbyte dot de
I support this re-opening-request... Since 5.3 __autoload() is definitly *not* "the last line of defense for PHP to find a class definition". That's simply wrong.

http://www.php.net/manual/en/language.oop5.autoload.php (Note #1 + Example #3)
http://www.php.net/manual/en/language.oop5.changelog.php (#5)
 [2012-06-10 17:54 UTC] rahuijts at tiscali dot nl
Please
- explain (and let the documentation show) why it is not possible to throw an exception in the __autoload function if a static call is made on a non-existing class, when it is possible to do so if a non-existing class is instantiated,
- or reopen this bug report to acknowledge that it should be possible in both cases but currently fails for static calls due to a bug in PHP.

The documentation indeed supports the case for this bug report, but to defend derick@php.net as well: the first part of his response is probably a template text when marking a report as "Not a bug". The rest of his message does not mention static calling, which is essential for the problem to occur, so I think he closed the report because he missed that point. Please let us know, because the current status is very confusing.
 [2012-10-31 11:53 UTC] denis at slik dot eu
Can't reproduce this anymore on 5.4.3.
Good riddance.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 18:01:29 2024 UTC