/    Sign up×
Community /Pin to ProfileBookmark

__autoload and E_STRICT

Hey.
I have a problem with PHP’s __autoload option when certain errors occurs. I have these test files to try to locate the problem.

index.php

[code=php]function class_load($sClass) {
include “message.php”;
}

function e_handler($errno, $errstr, $errfile, $errline) {
msg::add($errstr);
}

spl_autoload_register( “class_load” );
set_error_handler( “e_handler” );

include “badFile.php”;[/code]

message.php

[code=php]class msg {
public static function add($message) {
echo $message.”<br /><br />”;
}
}[/code]

badFile.php

[code=php]abstract class testClass {
abstract public static function();
}[/code]

When I execute index.php, the server will make an E_STRICT error because of the abstract static method in badFile.php. But, PHP does NOT call my autoload function. I get this error “Fatal error: Class ‘msg’ not found in …”;

Why does the autoload function not get called?

to post a comment
PHP

7 Comments(s)

Copy linkTweet thisAlerts:
@NogDogFeb 10.2011 — I believe it is because the __autoload() only will actually get called at run-time, whereas the include of the "bad" file is done at compile-time, so it happens first. To test that hypothesis, just move that include into the __autoload() function and see what happens.
Copy linkTweet thisAlerts:
@dk_zero-coolauthorFeb 10.2011 — Not sure on how I would put it in the autoload function. That function is not executed before the e_handler is executed.

I tried this instead

[code=php]function class_load($sClass) {
if($sClass == "msg") include "message.php";
else include "badFile.php"
}

function e_handler($errno, $errstr, $errfile, $errline) {
msg::add($errstr);
}

spl_autoload_register( "class_load" );
set_error_handler( "e_handler" );

// Invalid class to execute __autoload
badfile::inc(); [/code]


__autoload now includes the bad file, so I know it works but it still won't do it in the handler.

If I change the content in the bad file to trigger_error("", E_USER_ERROR); or some other valid level, __autoload works find in the handler. It just wont work with the E_STRICT level.
Copy linkTweet thisAlerts:
@dk_zero-coolauthorFeb 10.2011 — I tried putting class_exists("msg", true); in the handler, but that won't execute __autolaod either.
Copy linkTweet thisAlerts:
@NogDogFeb 10.2011 — OK, I may be missing what it is you want to do here, but the "bad" class has what amounts to a parse error, so when it gets included, it is going to generate a parse error at parse/compile time, [i]before[/i] the autoload and error-handler functions are registered, which will happen at run-time. The error-handler function will only be useful for errors which occur during run-time. If you want to test that, then maybe put something into the "bad" class that would cause a run-time error, such as fopen('bogus-file-name.xyz'), perhaps? But in general, your registered error-handler function will not be useful for catching parse errors (that's what a good IDE/editor and unit testing are for ? ).
Copy linkTweet thisAlerts:
@dk_zero-coolauthorFeb 10.2011 — My bad, I made a typing error in the bad file example.

The error I am triggering in that file is not a parse error do to the missing function name (Which I don't have in the real testing file). I am triggering an E_STRICT Notice because I try to register an abstract method as an static method.

The error handler is called successfully. It's inside the error handler where the problem occurs when I try to call the msg class which is not yet included. This is where I want the auto load function to step in and to it's job.
Copy linkTweet thisAlerts:
@NogDogFeb 10.2011 — Hmm...it may be a limitation of the error-handler process? I really don't know and didn't see anything in the manual to confirm or deny it. My only suggestion would be to have the error-handler function be part of a class, which would also contain that "msg" method. Then that class would be loaded when you registered the error-handler, something like:

ErrorHandler.php:
[code=php]
<?php
class ErrorHandler
{
// register this method:
public static function handler($errno, $errstr, $errfile, $errline)
{
self::message($errstr);
return true;
}

public static function message($message)
{
echo $message . "<br /><br />";
return true;
}
}
[/code]

TestClass.php:
[code=php]
<?php
abstract class TestClass {
abstract public static function foo();
}
[/code]

index.php:
[code=php]
<?php
function class_load($sClass)
{
include $sClass.".php";
}

spl_autoload_register("class_load");
set_error_handler(array('ErrorHandler', 'handler'));

// this should generate error:
TestClass::foo();
[/code]
Copy linkTweet thisAlerts:
@dk_zero-coolauthorFeb 11.2011 — Well, the real project where I need this is a bit more complex than my error handler testing files. There is a lot of different classes in separate files where some classes uses something from another class or classes etc. It's kind of like Linux packages, where one needs another which might need a third and so on.

I do have a manual class loader method, also used by the autoloader. Loading the needed classes manually works find, just that it breaks the point of having an autoload function.

I will work on it, see if a solution emerges.

Thanks for your time though, much appreciated ?
×

Success!

Help @dk_zero-cool spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.11,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...