Added by Stanislav Malyshev, last edited by Stanislav Malyshev on Jun 02, 2008  (view change)

Labels

 
(None)

This proposal is implemented as Zend_Loader_PluginLoader

Zend Framework: Zend_Loader plugin directory support - Stanislav Malyshev Component Proposal

Proposed Component Name Zend_Loader plugin directory support - Stanislav Malyshev
Developer Notes http://framework.zend.com/wiki/display/ZFDEV/Zend_Loader plugin directory support - Stanislav Malyshev
Proposers Stanislav Malyshev
Revision 1.0 (wiki revision: 14)

Table of Contents

1. Overview

While working with the Framework, it might be needed to use certain classes belonging to other libraries or class bundles. These classes do not reside inside Framework directories and sometimes do not follow same file structure conventions as the Framework. However, it would be convenient if such files could participate in Framework loading mechanisms - for example, if the user could configure the directory where the PEAR classes are kept and then use Framework class loader (automatically or manually) to access these classes. This would allow to use the same loading mechanism across the application and not try to navigate between different loading mechanisms using by libraries or re-invent loaders anew.

The present proposal is intended to allow Zend_Loader class support loading (and autoloading) sets of classes that do not reside in main framework directory. Also, it provides base for implementing plugin structures for custom plugin sets - i.e. tag or helper library for template engine or component set for CMS.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • The plugin loader will support autoloading classes from directories not residing in main Framework tree
  • The plugin loader will support framework naming scheme (X/Y/Z.php) and other naming schemes (e.g. X_Y_Z/X_Y_Z.php).
  • The plugin loader will be activated only when needed

4. Dependencies on Other Framework Components

  • Zend_Loader
  • Zend_Exception

5. Theory of Operation

The proposed functionality would allow the Framework loader to load - automatically or manually - classes that do not reside in the main framework directory, such as component sets, external libraries, etc. The filename that is derived from the class name can be composed in two ways - the "deep" way as Framework and PEAR do - i.e. class My_Class_Foo resides in My/Class/Foo.php - and the "shallow" way that is more suited for multiple unrelated components when class My_Class_Foo resides in My_Class_Foo/My_Class_Foo.php.

Also, the notion of prefix would be supported - i.e. if prefix "My_Classes" is defined, then class name My_Classes_DB_Table would be looked up in DB/Table.php in deep configuration and in DB_Table/DB_Table.php in shallow configuration.

The user would be also able to "hint" the loader which library the loaded class belongs to, thus shortening the search for the right file. It would not be necessary for the user to know where the library is located to load classes from it, and knowing the name would be optional - if it is not used, the search would be performed in all known libraries together with the include path.

The library set would be searched after the main include path is searched, and also would be searched whenever the class loading is attempted without specifying the directory. This should not have negative impact on the lookups, since if the file is not found in the include paths, it means either it does not exist (in which case we'd error out so slowdown doesn't matter) or it is found in one of the library directories, which means we would not find it using regular include path search. In the latter case, as described above using hinted manual loader might be recommended.

The search would go over all the library paths defined, using depth setting defined by the library path in each case, and try to resolve the class name with each path. If no resolution could be found, the exception is thrown.

TBD: we may want to think about joining loadClass with loadLibraryClass somehow, though because the former receives the directory list and the latter receives a hint it is not clear how to make it.

6. Milestones / Tasks

  • Milestone 0: Complete the proposal
  • Milestone 1: Collect feedback and refine the proposal
  • Milestone 2: Provided the proposal is deemed acceptable, initial implementation checked into the incubator
  • Milestone 3: Refine the implementation, document, create unit tests
  • Milestone 5: Merge into the main Zend_Loader class

7. Class Index

  • Zend_Loader

8. Use Cases

UC-01

Define prefixed class library with shallow naming scheme, use autoloader:

UC-02

Define non-prefixed library with deep naming scheme, named "pear", then use library hint to manually load class:

9. Class Skeletons

What is the problem that this proposal seeks to solve?
Note that "we can't do X in the current design" is not a valid requirement.
You must demonstrate why "X" is needed.

How would this work with autoloading? If I reference an unloaded class named "OS_Guess" and I have both a shallow and a deep library path defined, does the autoload callback try to load that class as OS/Guess.php or OS_Guess.php? Is it appropriate to try one and then the other and only throw an exception if neither exists?

The proposal seeks to allow the Framework user to use Framework loader to load classes other than ones in Framework. In big applications, it is common to have a number of "class sets" grouped together, and since the Framework already has loader mechanism, it would be nice if the FW developer could use it to organise his own classes along with Framework classes. It can be especially useful when implementing all kinds of the "plugin" schemes - one wouldn't have to reinvent the loading wheel each time one wants to create a plugin set.

As for resolving what OS_Guess means the best way would be, of course, to make it PEAR_OS_Guess and then have PEAR perfix to have its own path, deep or shallow as you wish. Unfortunately, if you didn't write PEAR this option is not available, so what would happen is that all library paths would be tried, in definition order, each with it's own depth setting as defined in setLibraryPath, and if none could lead to resolving the class correctly - the exception would be thrown. If two paths have resolution for a class - the case which should never happen in properly designed system - then the one defined first would win.

In my opinion Zend_Loader is useless if you're working with third-party code/libs.

Framework needs an autoloader that will search directories  and create map with founded classes and their paths.

Then it will be possible to have 2 (or more classes) per file which can deacrease load time. 

Having autoloader to search all files and map them would kind of defy the purpose since you'd have to read and parse all the files anyway, even if you don't need them.

That's indeed useless. Also, ZF itself does include mostly every class, you would ever need. And if there are classes left, they should (if they are properly written) only need some small tweaks to fit in the normal component layout.

I think you don't understand the purpose of the module. Zend Framework doesn't and can't include any class in existence, because it's just framework, it doesn't implement any possible function that can be implemented in PHP. Neither any possible function belongs to the Framework. Imagine CMS or something like MediaWiki or CRM system which allows to add user widgets or user code tags, etc. - they all have inside the plugin system that allows integrating third-party user code into the system. And they all build the infrastructure to support finding and loading such classes. However, the Framework ignores this infrastructure need currently, so any application author has to implement it's own plugin set - even in the Framework, MVC has it's own loader for helpers, even though we already have one loader. And so will every other library that has plugins - so we will have dozen of loaders inside framework, all duplicate code.

View the rest of this thread. Most recent comment: Oct 20, 2007
2 more comments by: Stanislav Malyshev, Bryce Lohr