+1
This new usage 'throw Zend::exception()' does not make any sense. The
rationale sounds like premature optimisation.
Here is an excerpt from lukas simth blog on bytecode caches[1]
"<arnaud_> does autoload have a performance impact when using apc ?
<Rasmus_> it is slow both with and without apc
<Rasmus_> but yes, moreso with apc because anything that is autoloaded
is pushed down into the executor
<Rasmus_> so nothing can be cached
<Rasmus_> the script itself is cached of course, but no functions or classes
<Rasmus_> Well, there is no way around that
<Rasmus_> autoload is runtime dependent
<Rasmus_> we have no idea if any autoloaded class should be loaded until
the script is executed
<Rasmus_> top-level clean deps would speed things up a lot
<Rasmus_> it's not just autoload
<Rasmus_> it is any sort of class or function declaration that depends
on some runtime context
<Rasmus_> if(cond) function foo...
<Rasmus_> if(cond) include file
<Rasmus_> where file has functions and classes
<Rasmus_> or heaven forbid: function foo() { class bar { } }"
The original question was in regard with autoload but mentions the
conditional includes as being a sub-optimal solution.
Conditional includes do not seem to be a good idea.
[1]http://pooteeweet.org/blog/538
Bill Karwin wrote:
I appreciate everyone's input on this discussion. I'd like to reach
closure on what we do with Zend::exception(). I will summarize my
viewpoint on this issue, and then give my proposed resolution:
- Calling Zend::exception() is nonstandard PHP usage. This is an
education issue for developers using the Zend Framework.
- The stack trace generated from an exception is also nonstandard,
holding the location of the call to Zend::exception() is the second
line, instead of the first. So knowing how to read a stack trace from
Zend Framework is also an education issue for developers.
- This affects usage of IDE tools, which may provide clickable stack
trace output. Developers will be confused that clicking on the stack
trace always opens the source of Zend::exception().
- Zend::exception() sets the file and line of the exception
instantiation, not the place where it's thrown. This means the file and
line is always set to Zend.php line 227. Accounting for this requires
additional code to set the file and line to the place that calls
Zend::exception, but that still wouldn't fix the stack trace.
- Lazy-loading exceptions can be achieved in a traditional manner by
putting require_once() inside the code-block that creates an exception.
- Lazy-loading may be unnecessary in an environment that uses a bytecode
cache. I assume that any application that prioritizes performance
enough to be affected by the overhead of loading exception classes
should be running a bytecode cache.
So I propose the following resolution:
- Remove instances of Zend::exception() throughout the ZF tree,
replacing them with traditional "throw new" usage.
- Mark the Zend::exception() function as deprecated in 0.7.0.
- Remove the Zend::exception() function from the Zend class in 0.8.0.
- Continue to implement each exception in a separate file. Not all
exception classes are no-op extensions to Zend_Exception; some do
contain custom methods.
- Individual component authors may implement lazy-loading by putting the
require_once() into each code block before instantiating an exception
class. But I don't think this should be required; it's fine to
require_once() exception classes once per file, at the top of the PHP
file, and rely on bytecode caching for performance improvement.
I grepped, and found we currently have 358 instances of using
Zend::exception(), and 652 instances of traditional usage ("throw new
Foo_Exception;") in the tree. So we are using Zend::exception() in only
one-third of the cases of throwing an exception.
Comments? Tomatoes?
Regards,
Bill Karwin
PS: I'm volunteering to make the edits to replace usage of
Zend::exception() with traditional exception usage.