Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

This proposal is implemented as Zend_Loader_PluginLoader

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

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: 15)

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

]]></ac:plain-text-body></ac:macro>

]]></ac:plain-text-body></ac:macro>

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Apr 09, 2007

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

    <p>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?</p>

    1. Apr 29, 2007

      <p>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. </p>

      <p>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. </p>

  2. Jul 06, 2007

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

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

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

    1. Jul 17, 2007

      <p>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. </p>

      1. Sep 24, 2007

        <p>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.</p>

        1. Sep 24, 2007

          <p>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. </p>

          1. Oct 19, 2007

            <p>I think the Framework loader is best left loading framework classes. CMS's, Wikis, etc. are <em>applications</em>; they are built <em>on top</em> of frameworks. So it makes perfect sense (to me) for the <em>application</em> developer to be responsible for finding his own files.</p>

            <p>If the application developer happens to be able to shove all his classes into a directory structure compatible with ZF's loader, then the ZF loader can be used for application files, as well as framework files.</p>

            <p>If your application has more complex loading requirements, the best thing to do, IMHO, is to write your own loader that implements the appropriate logic. Perhaps you could build a loader with the Strategy pattern, where one of the available loading strategies would be the ZF loader. That way your application would have a great deal of flexibility in how it found and loaded files, while maintaining ZF compatibility.</p>

            <p>FWIW, this proposal is vaguely similar to issue ZF-1681 that I reported a while back.</p>

            1. Oct 20, 2007

              <p>I think putting your own application classes into ZF hierarchy is a bad idea. ZF can be shared between projects, you files won't. ZF can be pre-installed on the system, application plugins can be installed at any time. </p>

              <p>I can not accept the argument of "if you need it, do it yourself" - the purpose of the framework is exactly to help people to do infrastructure tasks, especially ones that are repetitive and similar between many applications. Plugin systems and external libraries are exactly the tasks that happen very frequently and can be implemented as a part of the infrastructure. <br />
              The user would be just duplicating the code that already exists in the Framework, replacing some predefined variables - why force user to do that if we can provide him access to already existing and working function. </p>