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.


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

Reply via email to