PHP's PSR-0 standard uses namespace to do autoloading

Source: Internet
Author: User
Tags autoload spl php framework

Before you introduce PSR-0, let's talk about namespaces (NameSpace) and autoloading.

NameSpace (namespace)

Namespace is a new feature of the PHP5.3 release that addresses two types of problems encountered when writing a class library or application to create reusable code such as classes or functions:

1. User-written code conflicts with the name of a class/function/constant or third-party class/function/constant within PHP.
2. Create an alias (or short) name for a very long identifier name (usually defined to alleviate the first type of problem) and improve the readability of the source code.

Elements in the PHP namespace use the same principles as file systems. For example, the class name can be referenced in three ways:
1. Unqualified name, or class name that does not contain a prefix, such as $a =new foo (); or Foo::staticmethod ();. If the current namespace is Currentnamespace,foo, it will be resolved to Currentnamespace\foo. If the code that uses Foo is global and does not contain code in any namespace, Foo is parsed as Foo. Warning: If a function or constant in a namespace is undefined, the unqualified function name or constant name is resolved to the global function name or constant name. For details, see Using namespaces: Fallback global function name/constant name.
2. Qualify the name, or include the name of the prefix, for example $a = new Subnamespace\foo (); or Subnamespace\foo::staticmethod ();. If the current namespace is Currentnamespace, Foo will be parsed to Currentnamespace\subnamespace\foo. If the code that uses Foo is global and does not contain code in any namespace, Foo is parsed as Subnamespace\foo.
3. Fully qualified name, or contains the name of the global prefix operator, for example, $a = new \currentnamespace\foo (); or \currentnamespace\foo::staticmethod ();. In this case, Foo is always parsed into the literal name (literal name) Currentnamespace\foo in the code.

Also note that accessing any global class, function, or constant can use a fully qualified name, such as \strlen () or \exception or \ini_all.

<?phpuse My\full\classname as another, my\full\nsname; $obj = new Another; Instantiate a My\full\classname object $obj = new \another; Instantiate a another object $obj = new another\thing; Instantiate a My\full\classname\thing object $obj = new \another\thing; Instantiate a Another\thing object $ A = \strlen (' Hi '); Call global function strlen$b = \ini_all; Access Global Constants Ini_all$c = new \exception (' Error '); Instantiate Global class Exception?>

The above is a brief introduction of namespace, to this do not know the classmate or handful read the document bar. Namespace has been widely used in many new PHP projects. Especially with the popularity of composer, it is very necessary to understand the characteristics of.


autoloading (auto load)

Many developers write object-oriented applications to create a PHP source file for each class definition. A big annoyance is having to write a long list of contained (require, include) files at the beginning of each script (one file per class).

Autoloading, however, solves this problem by defining a/series AutoLoad function that will be called automatically when trying to use a class that has not yet been defined. By calling the AutoLoad function, the scripting engine has a last chance to load the required classes before PHP fails. This autoload function can be the default __autoload (), as follows:

<?phpfunction __autoload ($class _name) {    require_once $class _name. '. php ';} $obj  = new MyClass ();
You can also use Spl_autoload_register () to define our own __autoload () function in a more flexible way:

<?phpfunction my_autoload ($class _name) {require_once $class _name. '. php ';} Spl_autoload_register ("My_autoload"); $obj  = new MyClass ();
The above code registers the My_autoload () function with the __autoload stack, which takes the __autoload () function (the __autoload () function will no longer work, but it can be explicitly registered to the __autoload stack. Notice that the __autoload stack has just been mentioned, which means that we can register multiple autoload functions and load them sequentially according to the Order of registration (the third parameter of the Spl_autoload_register can be changed in this order).

Here we show the simplest example of the AutoLoad function, which, of course, can be used for many complex situations in the actual environment through the setting of some rules.

But if our project is dependent on some other project, we would have been able to run smoothly under their own independent loading rules, but it might not be good to fuse together. So can there be a generic load rule to solve this problem?

PSR-0

PSR is a series of standards/specifications published by the PHP Framework Interoperability Group (PHP Universal Framework Group), currently including a total of 4 psr-0~psr-4, And PSR-0 is one of the auto-loading standards (the subsequent PSR-4, known as the improved auto-load standard, is a complement to PSR-0. PSR-0 is used more broadly). Https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md

The following describes the conditions that are necessary for the automatic loading of specific interoperability:

Mandatory requirements
    • A fully qualified Namespace and Class must conform to such a structure \<vendor name>\ (<namespace>\) *<class name>
    • Each namespace must have a top-level namespace ("Vendor name" provider name)
    • Each namespace can have multiple sub-namespace
    • When loading from the file system, each namespace delimiter is converted to Directory_separator(operating system path delimiter)
    • In class name, each underscore (_) symbol is converted to directory_separator. In namespace, the underscore (_) symbol has no (special) meaning.
    • When loaded from the file system, the qualified namespace and class must end in . php.
    • Verdor name,namespaces,class names can be combined in uppercase and lowercase letters (case sensitive)
In addition, this rule may be followed: returns False if the file does not exist.
Example
    • \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
Underline in namespace and class name
    • \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
Examples of implementations

Here is a simple example of automatic loading according to the above criteria:

<?phpfunction AutoLoad ($className) {    //Here The $classname is generally referred to in namespace way, the beginning of the article has introduced    //removed $classname left of the ' \ ' This is a bug for PHP5.3, see https://bugs.php.net/50731    $className = LTrim ($className, ' \ \ ');    $fileName  = ";    $namespace = ";    Find the position of the last namespace delimiter    if ($lastNsPos = Strrpos ($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;}

Splclassloader implementation there is a Splclassloader implementation example, if you follow the criteria as above, you can use it for automatic loading. This is also the currently recommended class loading standard for PHP5.3. http://gist.github.com/221634
<?php/* * This software are provided by the COPYRIGHT holders and CONTRIBUTORS * "as was" and any EXPRESS OR implied WAR  Ranties, including, but not * LIMITED to, the implied warranties of merchantability and FITNESS for * A particular PURPOSE Is disclaimed. In NO EVENT shall the COPYRIGHT * OWNER OR CONTRIBUTORS is liable for any DIRECT, INDIRECT, incidental, * special, EXEMPLA RY, or consequential damages (including, but not * LIMITED to, procurement of substitute GOODS OR SERVICES; LOSS of Use, * DATA, OR profits; or business interruption) however caused and on any * theory of liability, WHETHER in contract, STRICT liability, OR TORT * (including negligence OR OTHERWISE) arising in any-out-of-the----the-software, even IF advised of the Possibi Lity of SUCH DAMAGE. * * This software consists of voluntary contributions made by many individuals * and is licensed under the MIT license. For more information, see * &LT;HTTP://WWW.DOCTRINE-PROJECT.ORG&GT;. * */** * splclassloadeR implementation that implements the technical interoperability * standards for PHP 5.3 namespaces and class names.  * * Http://groups.google.com/group/php-standards/web/psr-0-final-proposal?pli=1 * *//Example which loads classes for The Doctrine Common package in the *//Doctrine\common namespace. * $classLoader = new Splclassloader (' Doctrine\common ', '/path/to/doctrine '); * $classLoader->register (); * * @license http://www.opensource.org/licenses/mit-license.html mit License * @author Jonathan H. Wage <[email p rotected]> * @author Roman S. Borschel <[email protected]> * @author Matthew weier O ' Phinney <[email&nbsp ;p rotected]> * @author Kris wallsmith <[email protected]> * @author Fabien potencier <[email     protected]> */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-&GT;_INCLUDEP Ath = $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->_fi    Leextension = $fileExtension;     }/** * Gets the file extension of class files in the namespace of this class loader. * * @return String $fileExtension */Public Function getfileextension () {return $this->_fileexten    Sion     }/** * 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 ($cl                Assname, 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; }    }}

Finish.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.