Zend Framework - Zend.php rewritten
A few weeks ago, after some discussion with Darby Felton, Darby created a Jira issue, which stated that the recommended directory structure and use of svn:externals are incompatible. The recommended directory structure cannot be maintained by svn:externals because Zend.php is sibling to the Zend/ directory. The svn:externals property only works upon directories, not files. An alternative approach is to create a ZendFramework directory, which in turn contains the Zend library.
|library |-|ZendFramework |-|-|Zend |-|-|Zend.php |-|PEAR |-|SuperLib
Suffers from the problem of requiring each of the children directories of /library to be in the include path, resulting in suboptimal performance when working with multiple libraries.
After Bill Karwin sent a notice to the list, asking for feedback, a long discussion started. This led to a lot of usefull feedback, and justifications for splitting / cleaning up Zend.php, including:
- Why is Zend.php called Zend.php? Cleaning up the organization via splitting also helps reduce naming confusion amongst beginners.
- Solves the svn externals issue described above.
- Why should I load a “debug” function with every request?
- How can I add more debug functions for use when I do want/need it (possibly loaded on-demand, even in my production environment) in a manner consistent with existing debug functions that is “compatible” with other related functions other developers might contribute (i.e. where is the standardization to facilitate community development and enhancement of framework-level “bootstrap” type features?
- Where is a standard mechanism for developers to add “global” functionality to their ZF app (e.g. “plugins” for Zend.php)
- Why is the registry accessed via the oddly named functions in Zend.php?
- How should developers extend the functionality mixed into the current Zend.php?
After a while, we all agreed to opt for the following solution:
- Methods for class-loading move to Zend/Loader.php.
- Method isReadable() also moves to Zend/Loader.php because it doesn’t justify having another class for this one method. If we develop a Zend/Filesystem.php class in the future, we’ll move isReadable() and deprecate it in Zend/Loader.php.
- Redesign Registry methods to store a static object in the Zend/Registry.php class. Allow developer to specify which class to use for this static instance, to allow subclassing. But of course you can also create an instance of Zend_Registry in a traditional manner, with new.
- Registry also has static methods get() and put(), which correspond to the old Zend::registry() and Zend::register() methods. Internally, thse methods are simply $r = self::getInstance(); return $r[key]; and $r = self::getInstance(); $r[key] = value;.
- Method and const for version moves to Zend/Version.php.
- Method dump() moves to class Zend_Debug.
- Rewrite Zend.php methods to proxy to new classes, and mark them deprecated in ZF 0.9.0. Remove Zend.php in the subsequent ZF 1.0.0 RC1.
- Rewrite unit tests.
- Rewrite manual pages.
The benefits
- Zend Framework files contained in a single directory. This simplifies integration of a Zend Framework tree into an application tree. You could use svn:externals, for instance.
- Modular; you don’t have to load it if you don’t use it.
- Consistent; no confusing exceptions or non-standard practices
- Easily add additional functionality at a future date without bloating a core class (additional file loading or debugging methods, for example)
- Eliminates Zend.php class altogether—class is sometimes seen as confusing for new users who think they are including the entire framework or don’t understand the purpose of the class
- Only one class is required – Zend/Loader.php so the bootstrap will not grow.
The disadvantages
- May break backwards compatibility for applications built before 0.9 (beta).
- If additional functions are needed, then need to require_once additional classes.
Bill Karwin committed revision 3834, with a widespread change, implementing the proposal we’ve been discussing to refactor Zend.php.
How does this affect your application? - Update your code!
The registry, got some API changes, and is implemented based on the code in the class skeletons, with 2 alterations (see below).
Zend::__unsetRegistry() became Zend_Registry::_unsetRegistry() Zend::isRegistered() became Zend_Registry::isRegistered() Zend::registry() became Zend_Registry::get() Zend::register() became Zend_Registry::set() Zend::initRegistry() became Zend_Registry::setClassName() Zend::dump() became Zend_Debug::dump() Zend::loadClass() became Zend_Loader::loadClass() Zend::loadFile() became Zend_Loader::loadFile() Zend::isReadable() became Zend_Loader::isReadable() Zend::VERSION became Zend_Version::VERSION Zend::versionCompare() became Zend_Version::versionCompare() Zend::loadInterface() is deprecated and will no longer exist Zend::exception() is deprecated and will no longer exist
It’s quite a change, but most of your code can be fixed by some search and replacing.
Update: Rob Allen has more details!