-- 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/

Reply via email to