php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #42098 E_STRICT doesn't trigger __autoload()
Submitted: 2007-07-25 10:35 UTC Modified: 2013-09-18 08:13 UTC
From: nicolas dot grekas+php at gmail dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.2.3 OS: *
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: nicolas dot grekas+php at gmail dot com
New email:
PHP Version: OS:

 

 [2007-07-25 10:35 UTC] nicolas dot grekas+php at gmail dot com
Description:
------------
See code sample (tested with PHP 5.2.1)

Reproduce code:
---------------
<?php

error_reporting(E_ALL | E_STRICT);
set_error_handler('reportError');

function reportError($code, $message)
{
	return errorReporter::report($code, $message);
}

function __autoload($class)
{
	class errorReporter
	{
		static function report($code, $message) { echo $message, '<br />'; }
	}
}


// When uncommented, this triggers an E_NOTICE, so reportError() is called,
// which itself calls errorReporter::report(), which triggers __autoload(),
// which loads the errorReporter class, and everything is fine:

//unset($a);
//echo $a;


// This  triggers an E_STRICT, so things should be the same as above,
// exept that __autoload() is never called, so the errorReporter class is never loaded,
// so we end up with an E_FATAL... BUG

eval('
class A           { function toto(  ) {} }
class B extends A { function toto($a) {} }
');

Expected result:
----------------
Declaration of B::toto() should be compatible with that of A::toto()

Actual result:
--------------
Fatal error: Class 'errorReporter' not found in [...](35) : eval()'d code on line 3

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-08-03 07:13 UTC] nicolas dot grekas+php at gmail dot com
I updated my PHP, and this bug appears also with version 5.2.3
 [2007-08-17 21:13 UTC] jani@php.net
Of course it doesn't work for this exact error: It's caught during compile time. Only execute time errors can be caught with user error handler.

Try change the eval'd code to following:

eval('
class A           { function toto(  ) {} }
A::toto();
');

This works fine..and it's also E_STRICT error.. 
 [2007-08-17 21:26 UTC] nicolas dot grekas+php at gmail dot com
I made some tests, and found a workaround that prove that you are wrong: the problem is really that __autoload() is not called, and not that the error_handler is not called.

In reportError() the before the return and it works, just add:
class_exists('errorReporter', false) || __autoload('errorReporter');

and it works. This proves that the error handler is called. (btw, that's also why I added the "eval" thing in the example. Without the eval you would be right...)
 [2007-08-17 22:33 UTC] jani@php.net
Can you reproduce this without using eval() ?
 [2007-08-17 22:37 UTC] nicolas dot grekas+php at gmail dot com
yes, with an include :
replace the eval with include 'toto.php', where toto.php contains
<?php
class A           { function toto(  ) {} }
class B extends A { function toto($a) {} }
?>

this is how I hit the bug the first time
 [2007-08-17 22:40 UTC] jani@php.net
And that proves I'm right. __autoload() won't happen during compile.
And this error happens during compile -> autoload wont be triggered.

 [2007-08-17 22:54 UTC] nicolas dot grekas+php at gmail dot com
Ah ah ! You play with words :)

The first time, you said :
- "Only execute time errors can be caught with user error handler.",
and now:
- "during compile -> autoload wont be triggered"

You was wrong the first time ! And you may be right the second time.

But that's still a bug for me in this case. My workaround does exactily what PHP internals should do automagically, nothing more ! Please consider it quietly, I'm not submitting this bug for fun. I do know the workaround now. It's for others developpers around the world who enjoy PHP a its best...
 [2007-08-17 23:08 UTC] tony2001@php.net
>Ah ah ! You play with words :)

No, he just said the same thing in other words.

>The first time, you said :
>- "Only execute time errors can be caught with user error handler.",
>and now:
>- "during compile -> autoload wont be triggered"

There are two stages:
1) compile;
2) execute.

Compile-time errors cannot be caught, only execute-time errors can be.

>But that's still a bug for me in this case. My workaround does
>exactily what PHP internals should do automagically, nothing more !

This is how the things work.
 [2010-05-25 11:12 UTC] i at walkinraven dot name
I think autoload will not work in exception_handler or error_handler, that is the problem.
 [2011-09-14 11:51 UTC] phil at propcom dot co dot uk
This is related to https://bugs.php.net/bug.php?id=54054&edit=2 which I have just commented on proving some, hopefully, sane example code.
 [2012-12-28 10:55 UTC] nicolas dot grekas+php at gmail dot com
The error codes concerned by this bug are the ones used in Zend/zend_compile.c:
E_STRICT, E_DEPRECATED, E_NOTICE, E_WARNING, E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR and E_COMPILE_WARNING.
So virtually no error code is safe.

A workaround strategy at source code level would be to stack errors at compile time, then trigger them just when compile time is over.

Is it possible? Anyone as a better idea?
 [2013-09-18 08:13 UTC] tony2001@php.net
See detailed answer in bug #54054.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 02 07:01:30 2024 UTC