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
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
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 08:01:29 2024 UTC