+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.

Reply via email to