Re: [fw-general] Multiple spl_autoload registered handlers

2011-08-30 Thread Matthew Weier O'Phinney
-- Greg  wrote
(on Thursday, 25 August 2011, 11:55 AM -0500):
> > Thats not true.  Autoloaders that are shipped with code should only
> > be responsible for loading the code they are responsible for (in the
> > least).
> 
> Ok, I can agree with that. But thats were overheads can occur
> depending on the implementation of the rest of the spl registered
> handlers.
> 
> As example, suppose the StandardAutoloader has a registered namespace.
> And when the StandardAutoload::autoload function is called and it
> determines that the class name is for that namespace but the class can
> not be located then by returning false, the next registered spl
> autoloader is called - but we just determined that the autoloader
> shipped for that namespace could not find the class - so whats the
> point in asking any of the other autoloaders?

Here's an example:

 * You've created an application already, and have a classmap for its
   class resources.
 * You now need to develop a new feature for that application, which
   requires new classes. Most, if not all, of these are in a namespace
   that your classmap already knows.

This is exactly the situation the quickstart tries to accommodate. The
idea is this:

Zend\Loader\AutoloaderFactory::factory(array(
'Zend\Loader\ClassMapAutoloader' => array(__DIR__ .  
'/../library/.classmap.php'),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array('Application\View\Helper' => __DIR__ .  
'/../application/views/helpers'),
'prefixes'   => array(
'Default_View_Helper' => __DIR__ . 
'/../application/modules/default/views/helpers',
'Zend_View_Helper'=> __DIR__ .  
'/../library/Zend/View/Helper',
),
),
));

The above accommodates both the case where the classmap cannot identify
the class (a simple "isset($map[$classname])" check), as well as
checking specific namespaces and prefixes. 

One thing I've not mentioned: the StandardAutoloader allows you to
register multiple namespaces and/or vendor prefixes in a single
instance. Thus, if you're not using it as a fallback autoloader, it will
fail early -- if the class does not match a namespace/prefix in its
list, it returns false early. I think this is precisely the behavior
you're trying to describe; correct me if I'm wrong.

> For example, we want to find the Url view helper, heres our registered
> helper namespaces/prefixes.
> 
> $prefixes = array(
>   'Default_View_Helper_',
>   '\Application\View\Helper\',
>   'Zend_View_Helper_'
> );
> 
> 
> foreach($prefixes as $p) {
>   $class = $p . 'Url';
> 
>   if (class_exists($p . 'Url')) {
> return $this->helper['Url'] = new $class();
>   }
> }
> 
> If there are two spl registered handlers, ClassMap (which knows all of
> the classes in the application) and the StandardAutoloader (and in ZF2
> lets say it is fallback enabled). Then if 'Default_View_Helper_Url'
> does not exist in the ClassMap Autoloader why should the fallback
> strategy of the StandardAutoloader even be executed - it would be a
> waste of time and i/o (which for ZF1 is not possible to prevent, if I
> can recall, unless there is only one registered spl autoloader).

If you don't want it to hit the fallback strategy... then don't register
the fallback! 

The only reason we register it in the quickstart is for rapid
application development, when namespaces and vendor prefixes may be in
flux. If you don't want or need the fallback, simply don't register it
(it's off by default in the ZF2 StandardAutoloader). 

The reason to use _multiple_ autoloaders is if you have either multiple
autoloading strategies you want to employ (e.g. classmap for most-often
used classes, PSR-0 for others), or have several different codebases
with different class->file system mappings that require multiple
strategies (heck, this is true in ZF1 -- library code vs application
code hierarchies differ!). 

The recommendation for production is to _never_ use the fallback
autoloader strategy, and only use either classmaps, the
StandardAutoloader with explicit namespaces/dir or prefix/dir pairs, or
a combination of the two. These strategies ensure failing early.

-- 
Matthew Weier O'Phinney
Project Lead| matt...@zend.com
Zend Framework  | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

--
List: fw-general@lists.zend.com
Info: http://framework.zend.com/archives
Unsubscribe: fw-general-unsubscr...@lists.zend.com




Re: [fw-general] Multiple spl_autoload registered handlers

2011-08-25 Thread Greg
Hi Ralph,

>
> Thats not true.  Autoloaders that are shipped with code should only be
> responsible for loading the code they are responsible for (in the least).

Ok, I can agree with that. But thats were overheads can occur
depending on the implementation of the rest of the spl registered
handlers.

As example, suppose the StandardAutoloader has a registered namespace.
And when the StandardAutoload::autoload function is called and it
determines that the class name is for that namespace but the class can
not be located then by returning false, the next registered spl
autoloader is called - but we just determined that the autoloader
shipped for that namespace could not find the class - so whats the
point in asking any of the other autoloaders?

For example, we want to find the Url view helper, heres our registered
helper namespaces/prefixes.

$prefixes = array(
  'Default_View_Helper_',
  '\Application\View\Helper\',
  'Zend_View_Helper_'
);


foreach($prefixes as $p) {
  $class = $p . 'Url';

  if (class_exists($p . 'Url')) {
return $this->helper['Url'] = new $class();
  }
}

If there are two spl registered handlers, ClassMap (which knows all of
the classes in the application) and the StandardAutoloader (and in ZF2
lets say it is fallback enabled). Then if 'Default_View_Helper_Url'
does not exist in the ClassMap Autoloader why should the fallback
strategy of the StandardAutoloader even be executed - it would be a
waste of time and i/o (which for ZF1 is not possible to prevent, if I
can recall, unless there is only one registered spl autoloader).


Its fine, I can work with what is there.


Regards,

-- 
Greg

--
List: fw-general@lists.zend.com
Info: http://framework.zend.com/archives
Unsubscribe: fw-general-unsubscr...@lists.zend.com




Re: [fw-general] Multiple spl_autoload registered handlers

2011-08-25 Thread Ralph Schindler

Again, why is this a problem, exactly? What if you have another
autoloader registered later that _can_ handle it?


If the first dedicated autoloader for that namespace couldn't handle
it, chances are no other handler will (or should not).


Thats not true.  Autoloaders that are shipped with code should only be 
responsible for loading the code they are responsible for (in the least).


Try as we might, the one class per file / 1:1 mapping of 
namespace/classname to filesystem name is still just a suggested best 
practice, and we cannot cover every mapping a developer might come up 
with.  That's not to say their code (that you might want to consumer in 
your ZF application) is not useful, it just means we cannot autoload 
things that are not of a standard mapping.  I've still seen:


   * devs put class in the file name SomeClass.class.php
   * devs put multiple classes in a file
   * devs don't use logical prefixes or namespaces

Simply put, the best practice here is to let the 3rd party autoloader 
handle the 3rd party code.  Each autoloader should short-circut/return 
early if it is being asked to handle a class it is not responsible for.


The CONSUMER is ultimately responsible for properly organizing their 
spl_autoload_ stack in some bootstrapping process and ensuring the code 
they are consuming actually does play nice with other code.




But spl_autoload _IS_ a stack


I realize that, the point was that the application code cannot break
out of the execution loop if desired.


By the time you are executing your application, you should not be 
concerned with either the who, what, why, or how a class is located an 
utilized.  Simply put, that's too much information for the application 
layer.


This is the whole point of delegation. This is probably a good read for you:

http://en.wikipedia.org/wiki/Java_Classloader

Things are not so completely different with regards to how JVM and PHP 
have decided to solve the problem of dynamic class resolution.


Ultimately, if you're trying to influence which class of the SAME NAME 
your application is attempting to use, you probably have some bigger 
architectural issues to be dealing with.



As much as I appreciate that the zf2-quickstart example, is exactly
that, but it does somewhat exemplify the point I'm trying to make
since in that example, the StandardAutoloader would execute given the
namespaces registered even though there are class maps also - I
realize it is just example code.

My original post was more to draw awareness to potential overhead that
could be incurred if the we're not cognitive of the implications
(depending on how and what is being used).


What exactly is the overhead?  In all of my research, multiple small 
concise autoloaders are always faster than one monolithic autoloader.


The idea behind the Zend\Loader component is to give developers options. 
 The options allow developers the ability to write code that will play 
nice with older 3rd party code (think prefixed code) as well as newer 
3rd party code (namespaced).  Also also give developers to option to 
compile classmaps in situations where performance is a top priority.


-ralph


--
List: fw-general@lists.zend.com
Info: http://framework.zend.com/archives
Unsubscribe: fw-general-unsubscr...@lists.zend.com




Re: [fw-general] Multiple spl_autoload registered handlers

2011-08-25 Thread Greg
Hi Matthew,

>
> Again, why is this a problem, exactly? What if you have another
> autoloader registered later that _can_ handle it?

If the first dedicated autoloader for that namespace couldn't handle
it, chances are no other handler will (or should not).

>
> But spl_autoload _IS_ a stack

I realize that, the point was that the application code cannot break
out of the execution loop if desired.

As much as I appreciate that the zf2-quickstart example, is exactly
that, but it does somewhat exemplify the point I'm trying to make
since in that example, the StandardAutoloader would execute given the
namespaces registered even though there are class maps also - I
realize it is just example code.

My original post was more to draw awareness to potential overhead that
could be incurred if the we're not cognitive of the implications
(depending on how and what is being used).


Regards,

-- 
Greg

-- 
List: fw-general@lists.zend.com
Info: http://framework.zend.com/archives
Unsubscribe: fw-general-unsubscr...@lists.zend.com




Re: [fw-general] Multiple spl_autoload registered handlers

2011-08-25 Thread Matthew Weier O'Phinney
-- Greg  wrote
(on Wednesday, 24 August 2011, 09:29 PM -0500):
> Hi Matthew,
> > > My point, or preference is, is that we should try and encourage only
> > > registering one autoloader handler for the application.
> >
> > Why, exactly? What problem does this solve?
> >
> > This is in fact how the StandardAutoloader (PSR-0 implementation) in ZF2
> > works -- you register explicit namespace/path pairs; if the requested
> > class does not match the given namespace, it moves on to the next
> > handler.
> 
> In my opinion, therein lays the problem. Each handler's register
> method is registering with spl_autoload_register, which the developer
> cannot halt if a class for a particular namespace is not found, since
> the handler's autoload method typically returns false, causing the
> spl_autoloader to move onto the next registered handler (there is no
> way of preventing _spl_ from continuing?).

Again, why is this a problem, exactly? What if you have another
autoloader registered later that _can_ handle it?

> For example, say the StandardAutoloader is registered and has had
> namespace 'Ant' registered with it. And another handler is also
> registered with the spl_autoload_register (similar to what's in the
> quickstart). Then if class_exists is called for 'Ant\test', the
> standard autoloader will return false (since it doesn't exist),
> causing the spl_autoloader to move onto the next registered handler
> when it shouldn't, especially when chances are none of the other
> handlers know anything about that namespace.

While there may be some additional execution cycles, in most cases, the
logic behind autoloaders should be written such that the overhead is
minimal. This is, in fact, why we're advocating class maps and explicit
namespace/path pairs for ZF2 -- so that autoloaders can fail early and
quickly if they are incapable of locating a class file.

> So instead, I'm thinking, there should be only one (stack like)
> handler registered via spl_autoload_register, 

But spl_autoload _IS_ a stack

> and any other handlers would register with that single stack like
> handler instead of directly registering with the spl_autoloader. This
> would give the handler a way to indicate that the autoloading
> mechanism should halt its process and not waste any more cycles or
> file/io lookups.

So, would the idea of having AutoloaderFactory act as a priority stack,
registering a single entity with spl_autoload, but containing many
autoloader strategies internally, work for you? As mentioned before, the
autoloaders written for ZF2 pretty much work as you indicate -- they
fail early if they cannot locate the class file. 

This would also still allow developers to register additional
autoloaders when they want to provide alternate strategies to fall back
on.

> For example, with the ZF1 code I wanted to try an optimize the
> autoloading mechanism after introducing the Class Map back port you
> provided. Try making that handler the only autoloader for ZF1, its not
> clean. And with a class map to hand there is no need for the View
> Helper to file hunt, try changing file_exists to class_exists and
> notice the unnecessary subsequent autoloader calls if more than one
> handler is registered with spl.

This is the nature of autoloading -- it tries every strategy it can
until no more are possible before it fails. It's very useful to have
multiple strategies available, and to be able to intercept when one or
more fail.

-- 
Matthew Weier O'Phinney
Project Lead| matt...@zend.com
Zend Framework  | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

-- 
List: fw-general@lists.zend.com
Info: http://framework.zend.com/archives
Unsubscribe: fw-general-unsubscr...@lists.zend.com




Re: [fw-general] Multiple spl_autoload registered handlers

2011-08-24 Thread Greg
Hi Matthew,

>> My point, or preference is, is that we should try and encourage only
>> registering one autoloader handler for the application.
>
> Why, exactly? What problem does this solve?
>
> This is in fact how the StandardAutoloader (PSR-0 implementation) in ZF2
> works -- you register explicit namespace/path pairs; if the requested
> class does not match the given namespace, it moves on to the next
> handler.

In my opinion, therein lays the problem. Each handler's register
method is registering with spl_autoload_register, which the developer
cannot halt if a class for a particular namespace is not found, since
the handler's autoload method typically returns false, causing the
spl_autoloader to move onto the next registered handler (there is no
way of preventing _spl_ from continuing?).

For example, say the StandardAutoloader is registered and has had
namespace 'Ant' registered with it. And another handler is also
registered with the spl_autoload_register (similar to what's in the
quickstart). Then if class_exists is called for 'Ant\test', the
standard autoloader will return false (since it doesn't exist),
causing the spl_autoloader to move onto the next registered handler
when it shouldn't, especially when chances are none of the other
handlers know anything about that namespace.

So instead, I'm thinking, there should be only one (stack like)
handler registered via spl_autoload_register, and any other handlers
would register with that single stack like handler instead of directly
registering with the spl_autoloader. This would give the handler a way
to indicate that the autoloading mechanism should halt its process and
not waste any more cycles or file/io lookups.

For example, with the ZF1 code I wanted to try an optimize the
autoloading mechanism after introducing the Class Map back port you
provided. Try making that handler the only autoloader for ZF1, its not
clean. And with a class map to hand there is no need for the View
Helper to file hunt, try changing file_exists to class_exists and
notice the unnecessary subsequent autoloader calls if more than one
handler is registered with spl.


Regards,

Greg

-- 
List: fw-general@lists.zend.com
Info: http://framework.zend.com/archives
Unsubscribe: fw-general-unsubscr...@lists.zend.com




Re: [fw-general] Multiple spl_autoload registered handlers

2011-08-24 Thread Matthew Weier O'Phinney
-- Greg  wrote
(on Wednesday, 24 August 2011, 07:34 PM -0500):
> > > if (false === class_exists('ClassA')) { //dynamically check to see if
> > > a local overriding class exists via the autoloader
> > >   $class = new DefaultClass();
> > > } else {
> > >   $class = new ClassA();
> > > }
> >
> > What is an "overriding class"?
> 
> In the above 'overriding' is the 'preferred' class to use, else use a
> default one (which doesn't have to be of the same namespace).
> 
> > By doing that, you can be sure that the stack of autoloaders is
> > exactly as you expect it to be.  You can also use the PHP 5.3 only
> > feature of spl_autoload_register "prepend flag" to ensure things are
> > in the order you expect them to be in:
> 
> Even with the prepend flag it doesn't alleviate the problem, because
> if 'Class A' is not found in the first registered autoloader, all of
> the other (if any) autoloaders are then called - which in the above
> example would be unnecessary.
> 
> To me the problem is somewhat similar to finding a ZF1 View Helper, it
> iterates through until it finds one.
> 
> My point, or preference is, is that we should try and encourage only
> registering one autoloader handler for the application. 

Why, exactly? What problem does this solve?

Multiple autoloaders helps solve the problem of allowing different
autoloading strategies -- which may be due to performance
considerations, differences in filesystem hierarchies, etc. I'm not sure
why we would desire a single autoloader, so if you could provide some
use cases, that would help us better understand your arguments.

> I've also wonder it should be similar to ZF1's plugin priority stack, 

This is somewhat possible with spl_autoload(), as Ralph already
indicated; it's also trivially easy to create an optimistic autoloading
solution using SplPriorityQueue to loop through strategies.

> which may also then provide the developer more control of the
> execution stack (if needed). 

Currently in ZF2, we have an AutoloaderFactory, and you register
autoloaders in the order in which you want them searched. This could be
altered to use a priority queue internally. It's not exactly "a single
autoloader", but then again, it sounds a bit like you're mainly wanting
to be able to control the order of execution. This approach could solve
that.

> I realize that in ZF2 this may not be an issue if say
> only the Class Map autoloader is the only registered handler.

I don't anticipate this at all, actually. I anticipate a combination of
class map autoloading, PSR-0 autoloading with explicity namespace/path
pairs, and PSR-0 fallback include_path autoloading. This hybrid approach
makes for a good story from development (when namespaces and paths are
often in flux) to production (when you need to milk performance).

> For example, if the handler could prevent the autloader stack from
> automatically continuing onto calling the subsequent registered
> handlers because the one for that namespace knows it could not find
> and that none of the handlers will either.

This is in fact how the StandardAutoloader (PSR-0 implementation) in ZF2
works -- you register explicit namespace/path pairs; if the requested
class does not match the given namespace, it moves on to the next
handler.

-- 
Matthew Weier O'Phinney
Project Lead| matt...@zend.com
Zend Framework  | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

--
List: fw-general@lists.zend.com
Info: http://framework.zend.com/archives
Unsubscribe: fw-general-unsubscr...@lists.zend.com




Re: [fw-general] Multiple spl_autoload registered handlers

2011-08-24 Thread Greg
Hi Ralph,

>> if (false === class_exists('ClassA')) { //dynamically check to see if
>> a local overriding class exists via the autoloader
>>   $class = new DefaultClass();
>> } else {
>>   $class = new ClassA();
>> }
>
> What is an "overriding class"?


In the above 'overriding' is the 'preferred' class to use, else use a
default one (which doesn't have to be of the same namespace).

> By doing that, you can be sure that the stack of autoloaders is exactly as
> you expect it to be.  You can also use the PHP 5.3 only feature of
> spl_autoload_register "prepend flag" to ensure things are in the order you
> expect them to be in:

Even with the prepend flag it doesn't alleviate the problem, because
if 'Class A' is not found in the first registered autoloader, all of
the other (if any) autoloaders are then called - which in the above
example would be unnecessary.

To me the problem is somewhat similar to finding a ZF1 View Helper, it
iterates through until it finds one.

My point, or preference is, is that we should try and encourage only
registering one autoloader handler for the application. I've also
wonder it should be similar to ZF1's plugin priority stack, which may
also then provide the developer more control of the execution stack
(if needed). I realize that in ZF2 this may not be an issue if say
only the Class Map autoloader is the only registered handler.

For example, if the handler could prevent the autloader stack from
automatically continuing onto calling the subsequent registered
handlers because the one for that namespace knows it could not find
and that none of the handlers will either.


Regards,

-- 
Greg

--
List: fw-general@lists.zend.com
Info: http://framework.zend.com/archives
Unsubscribe: fw-general-unsubscr...@lists.zend.com




Re: [fw-general] Multiple spl_autoload registered handlers

2011-08-24 Thread Ralph Schindler
I think you might have meant to post this to the zf-contributors 
maillist where most ZF2 discussions are happening.



if (false === class_exists('ClassA')) { //dynamically check to see if
a local overriding class exists via the autoloader
   $class = new DefaultClass();
} else {
   $class = new ClassA();
}


What is an "overriding class"?  The idea in PHP 5.3 and ZF2 is that all 
classes exist within some namespace.  You should never have a class of 
the same name in the same namespace but on different places on the 
filesystem.



Having multiple registered spl_autoload handlers will incur
unnecessary cycles, and the developer will not have the ability of
controlling the autoloading stack (e.g circumventing it), I'm
wondering if it would be better to have one registered handler similar
to the ZF1 plugin priority stack.


If you are concerned with multiple code-bases playing nice together, you 
can always fore-go the Autoloader::register() method that most 
autoloaders have to to "auto-register" themselves, and simply pass the 
autoloader object to spl_autoload_register yourself.


By doing that, you can be sure that the stack of autoloaders is exactly 
as you expect it to be.  You can also use the PHP 5.3 only feature of 
spl_autoload_register "prepend flag" to ensure things are in the order 
you expect them to be in:


http://php.net/manual/en/function.spl-autoload-register.php

-ralph

--
List: fw-general@lists.zend.com
Info: http://framework.zend.com/archives
Unsubscribe: fw-general-unsubscr...@lists.zend.com




[fw-general] Multiple spl_autoload registered handlers

2011-08-16 Thread Greg
I'm not sure whether this may be an issue in the end or not. But I am
reading reference to fallback autoloader handlers which causes me
concern if the developer has to go through hoops to ensure that the
application only has one spl_autoload registered handler. My concern
here is that if a call to class_exists is used to determine whether a
custom (project/module specific) class should be loaded instead of a
default class I realize that there might be some grounds of a DI
but the following code is what concerns me:


if (false === class_exists('ClassA')) { //dynamically check to see if
a local overriding class exists via the autoloader
  $class = new DefaultClass();
} else {
  $class = new ClassA();
}


Having multiple registered spl_autoload handlers will incur
unnecessary cycles, and the developer will not have the ability of
controlling the autoloading stack (e.g circumventing it), I'm
wondering if it would be better to have one registered handler similar
to the ZF1 plugin priority stack.


-- 
Greg

-- 
List: fw-general@lists.zend.com
Info: http://framework.zend.com/archives
Unsubscribe: fw-general-unsubscr...@lists.zend.com