rfc:splclassloader

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

rfc:splclassloader [2011/11/08 03:18]
guilhermeblanco Added SplAutoloader interface
rfc:splclassloader [2017/09/22 13:28]
Line 1: Line 1:
-====== Request for Comments: SplClassLoader ====== 
-  * Version: 1.0 
-  * Date: 2010-03-22 
-  * Author: Guilherme Blanco <guilhermeblanco@hotmail.com> 
-  * Status: Voting at https://wiki.php.net/rfc/splclassloader/vote  
-  * First Published at: http://wiki.php.net/rfc/splclassloader 
- 
-===== Introduction ===== 
- 
-PHP 5 introduced the concept of autoloading classes. 
- 
-However, many different projects adopted their own approach for class loader.  
-In the mid of 2009, several lead developers started an initiative called PHP Standards Group (aka. Framework Interoperability Group), which is mainly focused on interoperability between different Open Source projects. 
- 
-After an extensive discussions, group came with the primary interoperability between them, which is formally named as PHP Standards Recommendation #0 (or PSR-0). 
- 
-PSR-0 focus on a flexible autoloader that could be used or shared between projects, structuring and organizing Object Oriented code. So any project that decides to be PSR-0 compliant just need to follow the defines rules defined in the next topic. 
- 
-===== Rules ===== 
- 
-The following rules must be implemented in order to make a project be compliant to PSR-0: 
- 
-  * A fully-qualified namespace and class must have the following structure \<Vendor Name>\(<Namespace>\)*<Class Name> 
-  * Each namespace must have a top-level namespace ("Vendor Name"). 
-  * Each namespace can have as many sub-namespaces as it wishes. 
-  * Each namespace separator is converted to a DIRECTORY_SEPARATOR when loading from the file system. 
-  * Each "_" character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR. The "_" character has no special meaning in the namespace. 
-  * The fully-qualified namespace and class is suffixed with ".php" when loading from the file system. 
-  * Alphabetic characters in vendor names, namespaces, and class names may be of any combination of lower case and upper case. 
- 
-===== Extended Rules for Proposal ===== 
- 
-Together with PSR-0 rules, for SplClassLoader we would also include a few valid rules that must be implemented, that addicts to original PSR-0 rules, not affecting any of the projects participants, but also improving the flexibility of autoloader: 
- 
-  * Allow a namespace to be mapped through multiple paths. 
-  * Make SplClassLoader silently fails if class is not found. This one is useful when using multiple instances of SplClassLoader in a single script. 
-  * Allow SplClassLoader to lookup in include_path. This is useful for projects that define their own on include_path, such as PEAR and Zend Framework. 
- 
-===== Flexibility of a Rule ===== 
- 
-Even though PSR-0 is strict, PHP cannot force php extension. Ideally, the file extension is customizable, but default approach would be the defined one in PSR-0. 
- 
-===== Initial missing support ===== 
- 
-PHP does not provide a single approach for any OO based autoloader, so initially a new interface is required, for anyone interested to implement their own Autoloader. From now on, let's name it as SplAutoloader. 
-The purpose of this interface is to bring the minimum contract that any interested to autoload their resources should follow.  
-Here is the proposed implementation: 
- 
-<code php> 
-/** 
- * SplAutoloader defines the contract that any OO based autoloader must follow. 
- * 
- * @author Guilherme Blanco <guilhermeblanco@php.net> 
- */ 
-interface SplAutoloader 
-{ 
-    /** 
-     * Defines autoloader to work silently if resource is not found. 
-     * 
-     * @const 
-     */ 
-    const MODE_SILENT = 0; 
-     
-    /** 
-     * Defines autoloader to work normally (requiring an un-existent resource). 
-     * 
-     * @const 
-     */ 
-    const MODE_NORMAL = 1; 
-     
-    /** 
-     * Defines autoloader to work in debug mode, loading file and validating requested resource. 
-     * 
-     * @const 
-     */ 
-    const MODE_DEBUG = 2; 
-     
-    /** 
-     * Creates a new Autoloader instance. 
-     * 
-     * @param integer $mode Autoloader work mode. 
-     */ 
-    public function __construct($mode = \SplAutoloader::MODE_NORMAL); 
-     
-    /** 
-     * Add a new resource lookup path. 
-     * 
-     * @param string $resourceName Resource name, namespace or prefix. 
-     * @param mixed $resourcePath Resource single path or multiple paths (array). 
-     */ 
-    public function add($resourceName, $resourcePath); 
-     
-    /** 
-     * Load a resource through provided resource name. 
-     * 
-     * @param string $resourceName Resource name. 
-     */ 
-    public function load($resourceName); 
-     
-    /** 
-     * Register this as an autoloader instance. 
-     * 
-     * @param boolean Whether to prepend the autoloader or not in autoloader's list. 
-     */ 
-    public function register($prepend = false); 
-     
-    /** 
-     * Unregister this autoloader instance. 
-     * 
-     */ 
-    public function unregister(); 
-} 
-</code> 
- 
-===== Usage Examples ===== 
- 
-The standards we set here should be the lowest common denominator for painless autoloader interoperability. You can test that you are following these standards by utilizing this sample SplClassLoader implementation which is able to load PHP 5.3 classes. 
- 
-  * \Doctrine\Common\IsolatedClassLoader  
-    * /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php 
-  * \Symfony\Core\Request  
-    * /path/to/project/lib/vendor/Symfony/Core/Request.php 
-  * \Zend\Acl  
-    * /path/to/project/lib/vendor/Zend/Acl.php 
-  * \Zend\Mail\Message 
-    * /path/to/project/lib/vendor/Zend/Mail/Message.php 
-  * \namespace\package\Class_Name  
-    * /path/to/project/lib/vendor/namespace/package/Class/Name.php 
-  * \namespace\package_name\Class_Name 
-    * /path/to/project/lib/vendor/namespace/package_name/Class/Name.php 
- 
-===== Example implementation ===== 
- 
-Below is an example function to simply demonstrate how the above proposed standards are autoloaded. 
- 
-<code php> 
-function autoload($className) 
-{ 
-    $className = ltrim($className, '\\'); 
-    $fileName  = ''; 
-    $namespace = ''; 
-     
-    if ($lastNsPos = strripos($className, '\\')) { 
-        $namespace = substr($className, 0, $lastNsPos); 
-        $className = substr($className, $lastNsPos + 1); 
-        $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; 
-    } 
-     
-    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; 
- 
-    require $fileName; 
-} 
-</code> 
- 
-===== SplClassLoader implementation ===== 
- 
-The following class is a sample SplClassLoader implementation that can load your classes if you follow the autoloader interoperability standards proposed above. It is the current recommended way to load PHP 5.3 classes that follow these standards. 
- 
-> NOTE: This implementation is not the proposed final. It requires two updates: 
->   * Multiple paths per namespace 
->   * Silent mode 
- 
-<code php> 
-<?php 
- 
-/** 
- * SplClassLoader implementation that implements the technical interoperability 
- * standards for PHP 5.3 namespaces and class names. 
- * 
- * http://groups.google.com/group/php-standards/web/final-proposal 
- * 
- * // Example which loads classes for the Doctrine Common package in the 
- * // Doctrine\Common namespace. 
- * $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine'); 
- * $classLoader->register(); 
- * 
- * @author Jonathan H. Wage <jonwage@gmail.com> 
- * @author Roman S. Borschel <roman@code-factory.org> 
- * @author Matthew Weier O'Phinney <matthew@zend.com> 
- * @author Kris Wallsmith <kris.wallsmith@gmail.com> 
- * @author Fabien Potencier <fabien.potencier@symfony-project.org> 
- */ 
-class SplClassLoader 
-{ 
-    private $_fileExtension = '.php'; 
-    private $_namespace; 
-    private $_includePath; 
-    private $_namespaceSeparator = '\\'; 
- 
-    /** 
-     * Creates a new <tt>SplClassLoader</tt> that loads classes of the 
-     * specified namespace. 
-     * 
-     * @param string $ns The namespace to use. 
-     */ 
-    public function __construct($ns = null, $includePath = null) 
-    { 
-        $this->_namespace = $ns; 
-        $this->_includePath = $includePath; 
-    } 
- 
-    /** 
-     * Sets the namespace separator used by classes in the namespace of this class loader. 
-     * 
-     * @param string $sep The separator to use. 
-     */ 
-    public function setNamespaceSeparator($sep) 
-    { 
-        $this->_namespaceSeparator = $sep; 
-    } 
- 
-    /** 
-     * Gets the namespace seperator used by classes in the namespace of this class loader. 
-     * 
-     * @return void 
-     */ 
-    public function getNamespaceSeparator() 
-    { 
-        return $this->_namespaceSeparator; 
-    } 
- 
-    /** 
-     * Sets the base include path for all class files in the namespace of this class loader. 
-     * 
-     * @param string $includePath 
-     */ 
-    public function setIncludePath($includePath) 
-    { 
-        $this->_includePath = $includePath; 
-    } 
- 
-    /** 
-     * Gets the base include path for all class files in the namespace of this class loader. 
-     * 
-     * @return string $includePath 
-     */ 
-    public function getIncludePath() 
-    { 
-        return $this->_includePath; 
-    } 
- 
-    /** 
-     * Sets the file extension of class files in the namespace of this class loader. 
-     * 
-     * @param string $fileExtension 
-     */ 
-    public function setFileExtension($fileExtension) 
-    { 
-        $this->_fileExtension = $fileExtension; 
-    } 
- 
-    /** 
-     * Gets the file extension of class files in the namespace of this class loader. 
-     * 
-     * @return string $fileExtension 
-     */ 
-    public function getFileExtension() 
-    { 
-        return $this->_fileExtension; 
-    } 
- 
-    /** 
-     * Installs this class loader on the SPL autoload stack. 
-     */ 
-    public function register() 
-    { 
-        spl_autoload_register(array($this, 'loadClass')); 
-    } 
- 
-    /** 
-     * Uninstalls this class loader from the SPL autoloader stack. 
-     */ 
-    public function unregister() 
-    { 
-        spl_autoload_unregister(array($this, 'loadClass')); 
-    } 
- 
-    /** 
-     * Loads the given class or interface. 
-     * 
-     * @param string $className The name of the class to load. 
-     * @return void 
-     */ 
-    public function loadClass($className) 
-    { 
-        if (null === $this->_namespace || $this->_namespace . $this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace . $this->_namespaceSeparator))) { 
-            $fileName = ''; 
-            $namespace = ''; 
-            if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) { 
-                $namespace = substr($className, 0, $lastNsPos); 
-                $className = substr($className, $lastNsPos + 1); 
-                $fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; 
-            } 
-            $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension; 
- 
-            require ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName; 
-        } 
-    } 
-} 
-</code> 
- 
-===== Example usage ===== 
- 
-<code php> 
-$classLoader = new SplClassLoader(\SplClassLoader::MODE_SILENT); 
-$classLoader->setFileExtension('.php'); 
-$classLoader->registerNamespace( 
-    'Doctrine\Common',  
-    array('/path/to/doctrine', '/path/to/another/folder/with/doctrine') 
-); // Namespace style 
-$classLoader->registerPrefix('PEAR_', '/path/to/pear'); // PEAR style 
-$classLoader->register(); 
-</code> 
- 
-===== Proposal and Patch ===== 
- 
-The final release version of PSR-0 is available at: [[https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md]] 
- 
-<del>A C extension is already available for usage, and can be grabbed at [[http://github.com/metagoto/splclassloader]]</del> 
- 
-An extension to SPL has been created from the original C extension and a [[https://bugs.php.net/bug.php?id=60128|feature request]] has been filled for documentation purposes. The new SPL extension preliminary patch can be found at: [[https://gist.github.com/1310352]]. The provided patch is a minimum working version of SplClassLoader, so it may still require some updates to address minimum issues highlighted after a deep code review. 
- 
-Main purpose of this proposal is to support both PEAR style directory organization and also Namespace directory organization. 
- 
-===== Implementation extension ===== 
- 
-According to new threads in php-standards list, it seems all derived implementations have included these extensions to original support: 
-  * Multiple paths per namespace 
-  * Silent mode as a flag 
- 
-This turns the RFC specification incompatible with current patch. Patch is going to be updated as soon as voting ends. 
- 
-===== Changelog ===== 
-  * 2011-11-07 Guilherme Blanco: Expanded extended rules. 
-  * 2011-10-25 David Coallier: Added the new SPL patch information and feature request link. 
-  * 2011-10-24 Guilherme Blanco: Expanded RFC documentation. Put it as ready for review. 
-  * 2010-03-22 Guilherme Blanco: Initial RFC creation. 
  
rfc/splclassloader.txt · Last modified: 2017/09/22 13:28 (external edit)