flightphp / core

An extensible micro-framework for PHP
https://docs.flightphp.com
MIT License
2.64k stars 407 forks source link

Flight autloader clashing with RedBeanPHP #56

Closed sah-comp closed 11 years ago

sah-comp commented 11 years ago

Hi there,

i am using Flight together with RedBeanPHP https://github.com/gabordemooij/redbean as ORM and after the latest changes on the Flight Loader class i noticed the problem that an exception is thrown when a class can not be found.

RedBean has something called FUSE. This mechanism will try to find a class that corresponds to a RedBean bean (which is something like a DataObject). So if you have a bean, e.g. called "person" and you call a method on person, RB will try to look for a class named Model_Person (using whatever autoloader there is) and pass the method call to that class, if found. If there is no class with that name, RedBean wants to continue with program flow, but with the latest Flight Loader changes an exception is thrown, halting the program flow.

I suggest the Loader class shall not throw an exception.

Please also review the issue posted at RedBean https://github.com/gabordemooij/redbean/issues/294 for more information.

mikecao commented 11 years ago

Flight has always thrown an exception when it can't load a class, but it always checks if it's the last autoloader on the stack before doing so. Meaning if the class is not found at that point, PHP would raise a fatal error which is not recoverable. With the exception you can at least recover by do this:

Flight::register('test', 'NonExistentClass');

try {
    Flight::test();
}
catch (Exception $ex) {
    // Do something
}

Alternatively you can skip the autoload by doing:

Flight::register('test', 'NonExistentClass');

if (class_exists('NonExistentClass', false)) {
    Flight::test();
}
else {
    // Do something
}

The order of initialization changed recently in Flight, so now it's probably more likely that the Flight autoloader is at the end of the stack, so that's why you're seeing the exception when you didn't before. So in your case it looks like it's ok to have a missing class, so you should handle situation that appropriately. Let me know if the above works for you.

sah-comp commented 11 years ago

Thank you for the suggestion.

I think this will not help me that much, because there may be many possible non existent classes. I would have to register each and every possible one as well as also wrap it into a try-catch block. For clearification: Redbean may use a Model_* class for every database table and relation combination.

I am thinking of registering my own autoloader class which could check if a classname begins with "Model" and if so return null, but how would i register a autoloader class which is the last on the stack when my index.php goes like https://github.com/sah-comp/bienlein/blob/master/public/index.php as then Flight will always be the last autloader on the stack, right?!

This brings me to the question; why do we need a Flight autoloader class anyway. Does composer not have one anyway?

mikecao commented 11 years ago

I guess the issue is with the class_exists function as well, since the default behavior is to try and autoload the class, which will cause problems is you don't explicitly pass in false. So I've removed the exception. Fixed in the latest commit 7e1a098f6cd8a5dcfc8fc7451508dc5f96ed00b5.

sah-comp commented 11 years ago

Thank you very much, it works now like a charm again.