Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="toc"><ac:parameter ac:name="outline">true</ac:parameter><ac:parameter ac:name="maxlevel">2</ac:parameter></ac:macro>
<ac:macro ac:name="note"><ac:parameter ac:name="title">Read the Requirements</ac:parameter><ac:rich-text-body>
<p>If you have not done so yet, please read the <ac:link><ri:page ri:content-title="Zend Framework 2.0 Requirements" /></ac:link>.</p></ac:rich-text-body></ac:macro>

<p>The following is a list of milestones for Zend Framework 2.0. The milestones listed are not comprehensive; instead, they detail initiatives that have cross-cutting concerns across the framework or which affect a large subset of components. Other refactoring and work will likely be done in parallel with these initiatives (e.g., "Zend\Cache" and "Zend\Uri" both have discussions and refactoring occurring at the time this is being written).</p>

<p>Additionally, these milestones are not providing implementation details. Each details the problems and concerns about the components targetted, and a list of goals. In most cases, the goals include profiling and analysis of the components in order to generate proposals for improvement and refactoring. A milestone will be considered as complete once the proposals are accepted and implemented in the ZF2 master branch.</p>

<p>In some cases, milestones may be done in parallel. In such cases, separate branches will be created and maintained for these initiatives.</p>

<p><em><strong>The general theme throughout these milestones is narrowing the scope of components, and ensuring a proper separation of concerns between components.</strong></em></p>

<h2>Milestone: Autoloading & Plugin Loading</h2>

<ac:macro ac:name="note"><ac:parameter ac:name="title">Proposals Ready</ac:parameter><ac:rich-text-body>
<p>Proposals for autoloading and plugin loading are now available:</p>
<ul>
<li><ac:link><ri:page ri:content-title="Proposal For Autoloading in ZF2" /></ac:link></li>
<li><ac:link><ri:page ri:content-title="Proposal For Plugin Loading in ZF2" /></ac:link></li>
</ul>
</ac:rich-text-body></ac:macro>

<p>Profile autoloading and plugin loading, and develop one or more alternate approaches to improve performance. The current approaches to autoloading and plugin loading are non-optimistic, and with poorly defined include_paths or large prefix-path stacks, negatively impact performance.</p>

<p>Additionally, plugin loading usage is difficult to document and understand for many, particularly the way the plugin prefix stack operates. Currently, the fact that plugins operate on a stack, and that the stack may or may not be manipulated automagically by other functionality in the framework, leads to confusion as to what plugin will be loaded. In general, plugins should be registered explicitly by name to avoid confusion.</p>

<p>Ideas already identified for consideration include:</p>

<ul>
<li>Autoloading:
<ul>
<li>Explicit class => file maps
<ul>
<li>Additionally, potentially caching class => file maps in in-memory caches such as APC, Zend Server's Shm cache, or memcached</li>
</ul>
</li>
</ul>
</li>
<li>Plugin loading:
<ul>
<li>short name => classname file maps</li>
<li>caching "failure" lookups that are expired only on addition of new plugin paths</li>
</ul>
</li>
</ul>

<p>Once approaches are finalized, identify what components in ZF are affected, and refactor these to use the new approaches.</p>

<h3>Goals</h3>

<ul>
<li>Eliminate stat calls when using an opcode cache, or reduce by a significant number (> 10%).</li>
<li>Simplify documentation of and use of plugin loading. Examples of plugin loading should be succinct, and understood in a single reading.</li>
</ul>

<h2>Milestone: Exceptions</h2>

<ac:macro ac:name="note"><ac:parameter ac:name="title">Proposal Ready</ac:parameter><ac:rich-text-body>
<p>A formal proposal for how ZF2 exceptions should be defined has been posted:</p>
<ul>
<li><ac:link><ri:page ri:content-title="Proposal for Exceptions in ZF2" /></ac:link></li>
</ul>
</ac:rich-text-body></ac:macro>

<p>The Zend Framework 1.X series standardized on a single exception class per component and/or subcomponent, with all exceptions deriving from "Zend_Exception". While this seemed useful at first, in practice it's rare (and typically pointless) to catch exceptions at that top-level. Additionally, having all exceptions derive from a single exception class means that we cannot extend more meaningful exceptions such as "InvalidArgumentException", "DomainException", etc. – all of which could be useful for generic try/catch blocks.</p>

<p>During the PHP Standards working group meeting in 2009, this topic was raised. PEAR is planning on the following:</p>

<ul>
<li>Each component defines a marker "Exception" interface</li>
<li>A variety of other exception classes would be created, each implementing the component's "Exception" interface, but extending either the base "Exception" class or a more specific SPL exception class.</li>
<li>Subcomponents could also define their own exceptions.</li>
</ul>

<p>This provides more flexibility in implementation. Additionally, it obviates the need for translatable exceptions in most cases, as the exception name can typically be descriptive of the condition – and documentation can provide language-specific explanations of the exceptions. </p>

<h3>Goals</h3>

<ul>
<li>Define marker exceptions for all components</li>
<li>Analyze what exceptions are thrown, and create specific exception types to cover the general cases</li>
</ul>

<h2>Milestone: Testing</h2>

<p>In the unit test suite, we have several issues needing to be addressed:</p>

<ul>
<li>A number of components write to the directories in which they reside. This is problematic for those bundling ZF for distribution – particularly Linux distributions, but also for LAMP bundles where the directory owner may differ from the user running the tests. All tests that write to the filesystem should write to the system temporary directory.</li>
<li>A number of test suites define classes consumed solely within their test suite – often defining them directly within the same file as the test case class. To make these re-usable, autoloadable, and to follow our own best practices (one class per file), these should be moved into their own file and within a directory that may be autoloaded. We have decided to use the directory "TestAsset" within each component for this purpose.</li>
<li>A number of test suites have non-class test assets (configuration files, XML files, etc.). We have typically standardized on using a "_files" directory per-component for these assets; however, we need to review each component and verify that such assets are properly placed.</li>
<li>We want to investigate the possibility of running tests in parallel. This could significantly impact efforts at continuous integration, allowing us to identify problems due to new code additions early.</li>
<li>Many test suites use large amounts of RAM and/or CPU. We wish to profile these suites to determine what the bottlenecks are, and whether the test suites may be doing more work than they should in order to test functionality.</li>
<li>In many cases, it would be nice to execute a component's test suite as well as all components depending on it (to ensure code changes do not affect dependent components). Currently, we have no infrastructure for this. (Solving this could also assist with Continuous Integration efforts.)</li>
</ul>

<h3>Goals</h3>

<ul>
<li>Ensure all test suites writing to the filesystem write to the system temporary directory (and perform cleanup when complete)</li>
<li>Ensure all test asset classes are moved to individual class files under a "TestAsset" namespace of the component's test suite.</li>
<li>Ensure all non-class test assets are in a "_files" hierarchy of their component's test suite.</li>
<li>Profile resource-consuming test suites and attempt to improve them.</li>
<li>Investigate the possiblity of running tests in parallel.</li>
<li>Develop scripts/techniques for testing both a given component as well as all components dependent on that component.</li>
</ul>

<h2>Milestone: MVC</h2>

<p>Zend Framework's MVC layer comprises a variety of components: "Zend\Application", "Zend\Controller", "Zend\Layout", "Zend\View", and "Zend\Form" being the most used and most visible. What follows is a quick summary of the issues seen in the current designs of these components, and is meant to serve as a starting point for proposals for refactoring each.</p>

<h3>MVC: Controller Layer</h3>

<p>ZF's MVC is powerful and flexible, but also presents a difficult workflow for newcomers to understand and fully utilize. It suffers from some anti-patterns (e.g., "Zend_Controller_Front" is a singleton; access to the helper broker is only via protected member, and it cannot be injected; etc.). Many of its compelling features also introduce unwanted performance degradations, but the architecture makes it difficult to opt-out of these features cleanly if you wish to optimize your application for performance.</p>

<ul>
<li>Module support has always been tacked-on at best. It is difficult to create modular applications due to lack of clear examples. Additionally, configuring modules, and having module-specific workflows are hard to accomplish with the current codebase.</li>
<li>The ability to execute multiple actions is of dubious use. While it could potentially allow building widgetized sites, it also promotes the idea of coding business logic into the controller layer (instead of the model layer), and introduces performance degradation. A better approach is via a combination of models and view helpers – but clear, concise examples of how to do this need to be developed.</li>
<li>Error handling is done via the aforementioned multiple action execution. This should likely be moved to an exception handler registered via the front controller, which would make it simpler to provide custom error pages and break out of the dispatch execution.</li>
<li>Actions should also be able to force a response to be delivered immediately. Currently, this is done through hacks such as calling "exit()" or "die()" – but at any point, any piece of code should be able to indicate that the response is complete and ready to be returned.</li>
</ul>

<h3>MVC: View Layer</h3>

<p>The View layer suffers from having too many responsibilities: tracking variables, filters, and helpers, as well as being responsible for script lookup and rendering. Loading helpers is a huge performance bottleneck due to the combination of overloading and plugin loading. Additionally, the helper system is very difficult for newcomers to understand ("where is the "doctype" method defined? what arguments does it take?"). Views can only utilize PHP scripts currently – there are no conveniences provided for retrieving views from elsewhere (e.g., database, web service, etc.). Layouts are tacked onto the system, but provide little benefit over simply rendering a new view.</p>

<h3>MVC: Forms</h3>

<p>Forms (and their subcomponents: elements, sub forms, display groups) have too many responsibilities. Each embeds at least one plugin loader, and proxies to those loaders to add prefix paths. Additionally, in most cases the plugins loaded are attached to internal chains – and these chains would provide more flexibility of implementation (and likely improve performance) if they could be handled as separate objects. The decorator pattern utilized should not be part of the form objects, but instead part of the view layer; the various form objects should be injected into decorator chains. This would help properly separate concerns (domain logic and presentation logic), and potentially simplify the story for designers cerating form markup.</p>

<h3>MVC: Zend\Application</h3>

<p>"Zend\Application" is relatively new to the ZF ecosystem. In most cases, it is doing what is expected, but there are a couple areas for improvement.</p>

<ul>
<li>Modules. "Zend\Application" should be able to conditionally configure modules based on the current request.</li>
<li>Performance. Currently, loading resources introduces a new bottleneck; likely, these issues will be solved with improved plugin loading capabilities, however.</li>
</ul>

<h3>MVC: Performance</h3>

<p>The current front controller workflow is difficult to optimize for performance. Additionally, the heavy reliance on dynamically-loaded plugins tends to degrade performance due the number of stat calls performed in each request.</p>

<h3>Goals</h3>

<ul>
<li>Develop a comprensive set of proposals for refactoring of each component.
<ul>
<li>Proposals must consider performance implications</li>
<li>Proposals must consider education implications</li>
<li>Proposals must consider modular usage</li>
</ul>
</li>
<li>Implement all accepted proposals</li>
</ul>

<h2>Milestone: Documentation</h2>

<ac:macro ac:name="note"><ac:parameter ac:name="title">Proposals Ready</ac:parameter><ac:rich-text-body>
<p>Proposals for documentation structure are now available:</p>
<ul>
<li><ac:link><ri:page ri:content-title="Proposal For Documentation in ZF2" /></ac:link></li>
</ul>
</ac:rich-text-body></ac:macro>

<p>Documentation of components must follow a standard format, to ensure predictability and ensure completeness and quality. During this milestone we will determine the format to be used, and reorganize the documentation to follow this format – as well as update documentation where we find required segments of documentation missing.</p>

<h3>Goals</h3>

<ul>
<li>Each component should have:
<ul>
<li>an introduction outlining the goals of the component</li>
<li>a "quick start" showing the typical use case of the component. If the component will typically be configured and instantiated via bootstrapping, this should be shown as well.</li>
<li>a section detailing configuration options</li>
<li>a section detailing available methods, with examples</li>
<li>a section of examples</li>
</ul>
</li>
<li>For components having "plugins" – helpers, filters, validators, etc. – we will also need to determine a format for displaying these.</li>
</ul>

<h2>Milestone: I18n/L10n</h2>

<p>One selling point of Zend Framework is its rich internationalisation and localisation layers. However, these layers have a number of recurring issues:</p>

<ul>
<li>Performance degradation. This is supposedly helped via optional caching; however, recent performance profiling shows that the caching generates no improvements when opcode caches are present, regardless of caching backend, indicating room for improvement. Additionally, in some cases we are coding solutions in userland PHP that now have ready solutions within the language itself (e.g., "DateTime" provides the bulk of functionality present in "Zend_Date" at this time, and performs things such as calculations at the C-level).</li>
<li>Inconsistencies between ZF APIs and PHP APIs. As a concrete example, most PHP developers are very familiar with the formats accepted by PHP's "date()", "strtotime()", and "DateTime" functionality. However, "Zend_Date" only understands ISO formats – leading to a disconnect. Wherever possible, PHP APIs should be honored, and other APIs provided as additional options to the functionality.</li>
<li>Due to a heavy usage of statics and global state, tests for components depending on "Zend_Locale" or one of its dependent classes will often fail when running the full test suite or combinations of component test suites. "Zend_Locale" needs to be refactored to make little to no use of statics and/or global state, to ensure proper isolation and encapsulation.</li>
</ul>

<h3>Goals</h3>

<ul>
<li>Profile i18n/l10n components and determine where and when bottlenecks occur, and develop a plan for improving performance in these components.</li>
<li>Analyze components to determine if they duplicate native PHP functionality; if so, refactor or remove them.</li>
<li>Refactor "Zend\Locale" (and potentially other i18n/l10n components) to no longer rely on static and/or global state, or to provide easier mechanisms for re-setting state.</li>
</ul>

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Aug 17, 2010

    <p>What about standardization of the many web service components? Are there any plans, that all service components can be used and configured in the same way? What about the internal implementation of each service component?</p>