Edit report at https://bugs.php.net/bug.php?id=54054&edit=1
ID: 54054
Comment by: ota dot mares at gmail dot com
Reported by: morpika at vipmail dot hu
Summary: Autoload not called in user-defined error handler
function in case of E_STRICT
Status: Open
Type: Bug
Package: *Programming Data Structures
Operating System: FreeBSD 8.0
PHP Version: 5.3.5
Block user comment: N
Private report: N
New Comment:
I have the same issue with a more complex setup using monolog, the custom
monolog
error handler and gelf as logger.
Instead of logging the message "Warning: The use statement with non-compound
name
'UnexpectedValueException' has no effect in ...IndexController.php on line 11"
the
php error handling hickups, resulting in following error: "Fatal error: Class
'Gelf\Message' not found in ...IndexController.php on line 11". Please note
that
the above warning is never shown or logged in this case. All you get is a
confusing fatal message.
In all other scenarios the logging works, which leads to the assumption that
the
autoloading never happens in the given case.
Previous Comments:
------------------------------------------------------------------------
[2012-12-27 09:41:18] nicolas dot grekas+php at gmail dot com
This bug is a duplicate of bug #42098.
------------------------------------------------------------------------
[2011-09-14 12:41:59] web at darrengordon dot net
The use of opcoding caching can cause this issue to not be reproducable.
Test steps:
------------
1. Enable opcode caching (APC), restart your httpd to ensure the opcode cache
is clean.
2. Request testa.php to trigger the E_STRICT.
Result:
---
*error_handler(): "Declaration of Bar::baz() should be compatible with that of
Foo::baz()"
Fatal error: Class 'Error' not found in /<path>/trigger_e_strict.php on line 3
3. Uncomment line #25: "include('doesntexist');" and re-request testa.php to
trigger the E_WARNING.
Result:
---
*error_handler(): "include(doesntexist): failed to open stream: No such file or
directory"
*__autoload(): "Error"
*Error::output()
*error_handler(): "include(): Failed opening 'doesntexist' for inclusion
(include_path='.:/<path>:/usr/share/php')"
*Error::output()
*error_handler(): "Declaration of Bar::baz() should be compatible with that of
Foo::baz()"
*Error::output()
4. Recomment line #25: "include('doesntexist');" and re-request testa.php to
trigger the E_STRICT.
Result:
---
*error_handler(): "Declaration of Bar::baz() should be compatible with that of
Foo::baz()"
*_autoload(): "Error"
*Error::output()
Expected result:
----
Steps 2. and 4. should output the same result as the code is identical.
Actual result:
----
Steps 2. and 4. output different results.
Step 2. behaves according to the "Actual result" of bug #54054.
Step 4. behaves according to the Expected result" of bug #54054.
Notes:
----
This behaviour should be noted when reproducing bug #54054 as it will cause the
issue to not be reproducable.
Environment:
----
PHP 5.3.2
Apache/2.2.14
Ubuntu 10.04.3 LTS
Code:
----
testa.php
---------
<?php
error_reporting(-1);
// Set error handler
set_error_handler('error_handler');
// Error handler
function error_handler($severity, $message)
{
echo "*error_handler(): \"$message\"\n";
return Error::output();
}
// Autoloader
function __autoload($class)
{
echo "*__autoload(): \"$class\"\n";
// Load class 'Error'
eval("class $class {
public static function output() { echo '*' . __CLASS__ .
'::output()\n'; }
}");
}
// Trigger E_WARNING - Uncomment to alter opcode cache
//include('doesntexist');
// Trigger E_STRICT
include('testb.php');
?>
testb.php
-----
<?php
// Trigger E_STRICT
class Foo { public function baz($var){} }
class Bar extends Foo { public function baz() {} }
?>
------------------------------------------------------------------------
[2011-09-14 11:43:03] phil at propcom dot co dot uk
This is still an issue.
The 2 test cases below should hopefully sum this up for you.
Case 1...
include() call fails and generates an E_WARNING
E_WARNING is caught by the error handler
Error handler attempts to use \Error class and calls the autoloader because it
is not currently loaded
...Case 2
The included file (http://codepad.viper-7.com/xyCn8C) generates an E_STRICT
E_STRICT is caught by the error handler
Error handler attempts to use \Error class and fails with a fatal error WITHOUT
calling the autoloader
The problem is that, in case 2, it is expected that the autoloader would be
used to load the \Error class. This doesn't appear to be the case.
Case 1: http://codepad.viper-7.com/b065B1
Case 2: http://codepad.viper-7.com/qi5185
Included file (xyCn8C) in Case 2: http://codepad.viper-7.com/xyCn8C
------------------------------------------------------------------------
[2011-02-19 14:39:37] morpika at vipmail dot hu
Description:
------------
__autoload function is not called in user-defined error handler function in
case of E_STRICT error. In case of any other type of errors (thet user-defined
error handler function can handle) the autoload function is called properly.
Test script:
---------------
test.php:
<?php
set_error_handler('php_error');
function php_error($errno, $errcode) { t_class::t_function($errno, $errcode); }
function __autoload($class_name) { echo 'autoload called'; exit; }
require('nf.php');
?>
nf.php (to create an E_STRICT ERROR: Redefining already defined constructor):
<?php
class number_format {
public function __construct() {}
public function number_format($number) { echo number_format($number, 0, '.',
'.'); }
}
?>
Expected result:
----------------
autoload called
Actual result:
--------------
Fatal error: Class 't_class' not found
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=54054&edit=1