power-media / prado3

Automatically exported from code.google.com/p/prado3
Other
0 stars 0 forks source link

Prado autoload() function throwing exception/fatal #445

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
The Prado autoload function is definited as:

public static function autoload($className)
    {
        include_once($className.self::CLASS_FILE_EXT);
        if(!class_exists($className,false) && !interface_exists($className,false))
            self::fatalError("Class file for '$className' cannot be found.");
    }

I had an issue with Propel's autoloader: even if I registered Prado's one as 
last autoloader, Propel's calls a class_exists() with a non-existent class (it 
checks for namespaced class but we're not using ns), thus calling Prado 
autoloader that throws a TPhpException.
I think that exception and fatal error management should not be part of the 
autoload, the caller should check it with class_exists or such.
Moreover, the if() block is unreachable if the include_once() fails, and the 
include_once() is redundant because the autoload is called if the class is not 
already loaded, so an include() should go as well, with less overhead.

I modified the function like this:

public static function autoload($className)
{
    if ((@include($className.self::CLASS_FILE_EXT)) !== false) {
        return true;
    }
    return false;
}

leaving to the external code the job to throw errors and check for class 
existence... am I doing it wrong?
What do you think about the above considerations?

Original issue reported on code.google.com by ciromat...@gmail.com on 28 Feb 2013 at 11:33

GoogleCodeExporter commented 8 years ago
If the Prado autoloader is installed as the last one and is throwing an 
exception, then that means that you already have a fatal problem there, because 
the class you're trying to instantiate can not be found. So you already have a 
problem in your applicatin - and Prado's just exposing it. Leaving the job of 
throwing the exception to some other code (to what code?) wouldn't solve the 
problem at that point.

That said failure to load a class can have two reasons:
1. the class file itself does not exist on the include path
2. the class file itself does exist and has been found, but there's a problem 
with parsing your the file or the class, which prevents the class in it 
actually getting defined in the PHP runtime environment. 

So I'd begin tracking down the problem first by checking whether you do 
actually have the class file for the class you want to instantiate, whether 
it's directory is on your include path, and whether there are any errors while 
loading/parsing the file (which could be checked by you include()ing it 
"manually" right prior to the instantiation attempt).

Original comment by google...@pcforum.hu on 3 Mar 2013 at 3:08

GoogleCodeExporter commented 8 years ago
I'm not concerning a class instantiation in my code, the issue is calling 
class_exists() to *prevent* instantiation of non-existent classes, which should 
return FALSE and not throw a fatal.

For what it matters, calling include_once does not either allow reaching the 
Prado::fatalError() call.

Original comment by ciromat...@gmail.com on 3 Mar 2013 at 6:41

GoogleCodeExporter commented 8 years ago
Basically any usage of a not-existing (or misspelled) class or every syntax 
error in a class file will result in an autoloading failure; prado assumes that 
you actually need the class you're trying to load, and then stops the execution 
flow reporting the error as fatal.
I myself had problems in the past with this behavior of prado, when including 
3rd party code that uses another autoloader: a typical workaround is to 
register the prado autoloader as the last in the chain.

Imho the benefits of the proposed change won't pay back the loss of basic error 
reporting.

Original comment by ctrlal...@gmail.com on 3 Mar 2013 at 10:39