-- A.J. Brown <[email protected]> wrote (on Saturday, 07 November 2009, 12:48 PM -0500): > That makes sense, but in the situation I had previously, the exception > was making it through to my code. When I tried to catch it, it > wouldn't catch. > > for example: > > $al = Zend_Loader_Autloader::getInstance(); > $al->suppressNotFoundWarnings( true ); > > try { > $al->autoload( 'Non_Existing_Class ); > } catch ( Zend_Exception $ ) { > //do nothing > } > > was throwing an exception for me.
I've gone through the code to trace execution, and there's no way Zend_Loader_Autoloader::autoload() is throwing an exception; if you're seeing differently, there's likely something funky with your install, or the exception is occuring in a place different than you think. I recommend stepping through execution with a debugger to see when and where the exception is being raised. > On Fri, Nov 6, 2009 at 2:20 PM, Matthew Weier O'Phinney > <[email protected]> wrote: > > -- A.J. Brown <[email protected]> wrote > > (on Friday, 06 November 2009, 01:33 PM -0500): > >> Thanks a lot, that worked. The only modification is to add the @ > >> symbol before the `include` in the new autoloader to suppress the > >> warnings. > >> > >> One question remains, though -- why was I not able to catch the > >> exception thrown by Zend's autoloader? Is it because it uses > >> call_user_func? I think this needs to be filed as a bug. I'll do the > >> honors if you agree. > > > > Zend_Loader_Autoloader::_autoload() has a try/catch block within it; if > > an exception occurs during Zend_Loader::loadClass(), it catches the > > exception and returns boolean false. This was by design; failure to > > autoload a class is not an exceptional condition. PHP will raise a fatal > > error later if the class is not found, but there may be other > > autoloaders registered and executed later that could potentially match > > the class. > > > >> On Fri, Nov 6, 2009 at 9:34 AM, Matthew Weier O'Phinney > >> <[email protected]> wrote: > >> > -- A.J. Brown <[email protected]> wrote > >> > (on Wednesday, 04 November 2009, 11:31 AM -0500): > >> >> Just incase it's useful somehow, here's the full config: > >> >> > >> >> http://www.pastie.org/683340 > >> >> > >> >> By the way, I'm aware that I shouldn't be registering Doctrine's > >> >> namespace and instead should push the Doctrine autoloader. I'm just > >> >> doing this temporarily until we begin actually leveraging doctrine. > >> >> > >> >> Here is the complete code of the class that's giving me trouble: > >> >> > >> >> http://www.pastie.org/683348 > >> > > >> > I figured it out. > >> > > >> > So, Zend_Loader_Autoloader utilizes Zend_Loader::loadClass() internally > >> > to resolve class files. However, I was wrong about how it works -- it > >> > *does*, in fact, throw an exception if the class does not exist after it > >> > attempted to load it. > >> > > >> > Your best bet is to create an additional autoloader that you attach to > >> > Zend_Loader_Autoloader that will attempt to load just your form classes > >> > -- and declare them otherwise. > >> > > >> > One way to do that might be as follows: > >> > > >> > class CP_Form_Autoloader > >> > { > >> > public static function autoload($className) > >> > { > >> > if (class_exists($className, false)) { > >> > return $className; > >> > } > >> > > >> > $fileName = str_replace('_', '/', $className) . '.php'; > >> > if (include($fileName)) { > >> > return $className; > >> > } > >> > > >> > eval("class $className extends CP_Form { }"); > >> > > >> > return $class; > >> > } > >> > } > >> > > >> > You would then register this with the main autoloader as follows: > >> > > >> > $al = Zend_Loader_Autoloader::getInstance(); > >> > class_exists('CP_Form_Autoloader'); // to ensure it's autoloaded > >> > // prior to registration... > >> > $al->pushAutoloader(array('CP_Form_Autoloader', 'autoload'), > >> > 'CP_Form_') > >> > > >> > Note the second argument -- this will ensure it only attempts to load > >> > classes beginning with 'CP_Form_'. > >> > > >> > Do the above in a bootstrap resource, and then modify your CP_Form > >> > class's _declareFormClass() method as follows: > >> > > >> > protected function _declareFormClass($formName) > >> > { > >> > $class = 'CP_Form_' . $formName; > >> > return $class; > >> > } > >> > > >> > and that *should* get you going. > >> > > >> >> And here's the complete source of the controller where that code is > >> >> being run: > >> >> > >> >> http://www.pastie.org/683344 > >> >> > >> >> On Wed, Nov 4, 2009 at 11:22 AM, A.J. Brown <[email protected]> wrote: > >> >> > Hey Matthew, > >> >> > > >> >> > Thanks for the explanation. I assumed since the error had > >> >> > "Zend_Exception" in it, that it was actually an exception being > >> >> > thrown. > >> >> > > >> >> > Zend_Version::VERSION == '1.9.3' > >> >> > > >> >> > The code in the pastie is literally the only code that ever does > >> >> > anything with the autoloader. This is a new project, and other than > >> >> > some boilerplate controller code, this is the first few lines of code > >> >> > that have been typed. The only other modifications are adding the > >> >> > namespaces to the autoloader, using the built-in method through the > >> >> > application configuration: > >> >> > > >> >> > > >> >> > autoloaderNamespaces.cp = "CP_" > >> >> > autoloaderNamespaces.doctrine = "Doctrine_" > >> >> > > >> >> > > >> >> > It's also strange that the error is not being suppressed by the @ > >> >> > symbol. > >> >> > > >> >> > > >> >> > On Wed, Nov 4, 2009 at 8:57 AM, Matthew Weier O'Phinney > >> >> > <[email protected]> wrote: > >> >> >> -- A.J. Brown <[email protected]> wrote > >> >> >> (on Tuesday, 03 November 2009, 07:59 PM -0500): > >> >> >>> I'm trying to supress errors with the Zend Autoloader, but it's > >> >> >>> still > >> >> >>> throwing them. In this specific case, I'm dynamically ceating a > >> >> >>> class > >> >> >>> if it doesn't already exist. I'm calling suppressNotFoundWarnings( > >> >> >>> true ). > >> >> >>> > >> >> >>> Here's my code: > >> >> >>> > >> >> >>> http://www.pastie.org/682603 > >> >> >>> > >> >> >>> On line 13, I'm getting a Zend_Exception saying that > >> >> >>> CP/Form/Login.php > >> >> >>> not found and CP_Form_Login does not exist. Here's that line: > >> >> >>> > >> >> >>> if( @$autoloader->autoload( $class ) ) { > >> >> >>> > >> >> >>> even wrapping it in a Try/Catch doesn't catch the exception. The > >> >> >>> best > >> >> >>> part is that further down in the code, the class is still declared, > >> >> >>> and the code continues to run. > >> >> >>> > >> >> >>> the CP_ namespace is registered to the autoloader at bootstrap. (I > >> >> >>> confirmed this through debugging). > >> >> >> > >> >> >> You're confusing exceptions with errors. Zend_Loader_Autoloader does > >> >> >> not > >> >> >> throw exceptions within its autoload() method (it's considered a bad > >> >> >> practice, and PHP itself behaves badly when it happens); this is why > >> >> >> the > >> >> >> try/catch does not work. What's actually happening is that PHP's > >> >> >> include() function is raising a PHP warning when it can't find the > >> >> >> related file in question. > >> >> >> > >> >> >> What *is* odd to me is that the autoloader is not suppressing the > >> >> >> errors > >> >> >> when you've specifically requested it do so. I've just tried this > >> >> >> locally with the following: > >> >> >> > >> >> >> > >> >> >> $autoloader->suppressNotFoundWarnings(true); > >> >> >> if (!$autoloader->autoload('Zend_Foo_Bar')) { > >> >> >> echo 'Not found'; > >> >> >> exit; > >> >> >> } > >> >> >> echo 'Found'; > >> >> >> > >> >> >> With the warnings suppressed, it works as expected; without, I get > >> >> >> the PHP warning, again, as expected. > >> >> >> > >> >> >> So, a few questions: > >> >> >> > >> >> >> * What version of ZF are you using? > >> >> >> * Can you provide *all* code indicating how you've configured the > >> >> >> autoloader? > >> >> >> * Is the "CP_" namespace registered with the autoloader? If not, do > >> >> >> you > >> >> >> have another autoloader registered that would be handling it? > >> >> >> > >> >> >> Based on what you've presented, I have to assume that there's some > >> >> >> other > >> >> >> configuration issue that's leading to the error. > >> >> >> > >> >> >> -- > >> >> >> Matthew Weier O'Phinney > >> >> >> Project Lead | [email protected] > >> >> >> Zend Framework | http://framework.zend.com/ > >> >> >> > >> >> > > >> >> > > >> >> > > >> >> > -- > >> >> > A.J. Brown > >> >> > web | http://ajbrown.org > >> >> > phone | (937) 660-3969 > >> >> > > >> >> > >> >> > >> >> > >> >> -- > >> >> A.J. Brown > >> >> web | http://ajbrown.org > >> >> phone | (937) 660-3969 > >> >> > >> > > >> > -- > >> > Matthew Weier O'Phinney > >> > Project Lead | [email protected] > >> > Zend Framework | http://framework.zend.com/ > >> > > >> > >> > >> > >> -- > >> A.J. Brown > >> web | http://ajbrown.org > >> phone | (937) 660-3969 > >> > > > > -- > > Matthew Weier O'Phinney > > Project Lead | [email protected] > > Zend Framework | http://framework.zend.com/ > > > > > > -- > A.J. Brown > web | http://ajbrown.org > phone | (937) 660-3969 > -- Matthew Weier O'Phinney Project Lead | [email protected] Zend Framework | http://framework.zend.com/
