目录
NameSpace(命名空间)
Autoloading(自动加载)
PSR-0
强制要求
例子
NameSpace和Class Name中的下划线
实现的范例
SplClassLoader 的实现
首页 后端开发 php教程 PHP的PSR-0标准利用namespace来做autoloading

PHP的PSR-0标准利用namespace来做autoloading

Jun 23, 2016 pm 01:51 PM
php 使用 标准

介绍PSR-0之前,先来说说命名空间(NameSpace)和Autoloading吧。

NameSpace(命名空间)

namespace是PHP5.3版本加入的新特性,用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:

1.用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
2.为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

PHP 命名空间中的元素使用了类似文件系统的原理。例如,类名可以通过三种方式引用:
1.非限定名称,或不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为 currentnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。详情参见 使用命名空间:后备全局函数名称/常量名称。
2.限定名称,或包含前缀的名称,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo。
3.完全限定名称,或包含了全局前缀操作符的名称,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo。

另外注意访问任意全局类、函数或常量,都可以使用完全限定名称,例如 \strlen() 或 \Exception 或 \INI_ALL。

<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // 实例化一个 My\Full\Classname 对象$obj = new \Another; // 实例化一个Another对象$obj = new Another\thing; // 实例化一个My\Full\Classname\thing对象$obj = new \Another\thing; // 实例化一个Another\thing对象$a = \strlen('hi'); // 调用全局函数strlen$b = \INI_ALL; // 访问全局常量 INI_ALL$c = new \Exception('error'); // 实例化全局类 Exception?>
登录后复制

以上是namespace的简要介绍,对此不了解的同学还是把细读文档吧。在众多新的PHP项目中,namespace已经被普遍使用了。尤其是伴随Composer的流行,它已经是很有必要去了解的特性了。


Autoloading(自动加载)

很多开发者写面向对象的应用程序时对每个类的定义建立一个 PHP 源文件。一个很大的烦恼是不得不在每个脚本开头写一个长长的包含(require, include)文件列表(每个类一个文件)。

而Autoloading,就是解决这个问题的,通过定义一个/系列autoload函数,它会在试图使用尚未被定义的类时自动调用。通过调用autoload函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。这个autoload函数可以是默认的__autoload(),如下:

<?phpfunction __autoload($class_name) {    require_once $class_name . '.php';}$obj  = new MyClass();
登录后复制
也可以采用更灵活的方式,通过spl_autoload_register()来定义我们自己的__autoload()函数:

<?phpfunction my_autoload($class_name) {	require_once $class_name . '.php';}spl_autoload_register("my_autoload");$obj  = new MyClass();
登录后复制
以上代码将my_autoload()函数注册到__autoload栈中,从而取到__autoload()函数(__autoload()函数将不再起作用,但可以显式的将其注册到__autoload栈)。注意到刚才提到了__autoload栈,意味着我们可以注册多个autoload函数,根据注册的顺序依次加载(通过spl_autoload_register的第三个参数可以改变这一顺序)。

在这里我们展示了autoload函数最简单的例子,当然通过一些规则的设置,也可以胜任实际环境中许多复杂的情况。

但是如果我们的项目依赖某些其他的项目,本来大家在各自独立的加载规则下能顺利运行,但融合在一起可能就不妙了。那么能否有一种通用的加载规则来解决这个问题?

PSR-0

PSR是由PHP Framework Interoperability Group(PHP通用性框架小组)发布的一系列标准/规范,目前包括了PSR-0~PSR-4共4个,而PSR-0就是其中的自动加载标准(其后的PSR-4称为改进的自动加载的标准,是PSR-0的补充。PSR-0使用更广泛)。https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md

下面描述了具体互操作性的自动加载所必须的条件:

强制要求

  • 一个完全合格的namespace和class必须符合这样的结构 \\(\)*
  • 每个namespace必须有一个顶层的namespace("Vendor Name"提供者名字)
  • 每个namespace可以有多个子namespace
  • 当从文件系统中加载时,每个namespace的分隔符要转换成 DIRECTORY_SEPARATOR(操作系统路径分隔符)
  • 在CLASS NAME(类名)中,每个下划线(_)符号要转换成DIRECTORY_SEPARATOR。在namespace中,下划线(_)符号是没有(特殊)意义的。
  • 当从文件系统中载入时,合格的namespace和class一定是以 .php 结尾的
  • verdor name,namespaces,class名可以由大小写字母组合而成(大小写敏感的)
  • 除此之外可能还会遵循这个规则:如果文件不存在则返回false。


    例子

  • \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和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
  • 实现的范例

    下面是一个按照如上标准进行自动加载的简单范例:

    <?phpfunction autoload($className){    //这里的$className一般是用namespace的方式来引用的,文章开头已有介绍    //去除$className左边的'\' 这是PHP5.3的一个bug,详见https://bugs.php.net/50731    $className = ltrim($className, '\\');    $fileName  = '';    $namespace = '';    //找到最后一个namespace分隔符的位置    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 的实现

    下面有一个SplClassLoader 的实现范例,如果你遵循了如上的标准,可以用它来进行自动加载。这也是目前PHP5.3推荐的类加载标准。 http://gist.github.com/221634

    <?php /* * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, 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 WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This software consists of voluntary contributions made by many individuals * and is licensed under the MIT license. For more information, see * <http://www.doctrine-project.org>. */ /** * 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 <jonwage> * @author Roman S. Borschel <roman> * @author Matthew Weier O'Phinney <matthew> * @author Kris Wallsmith <kris.wallsmith> * @author Fabien Potencier <fabien.potencier> */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;        }    }}</fabien.potencier></kris.wallsmith></matthew></roman></jonwage>
    登录后复制

    完。


    本站声明
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    热AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智能驱动的应用程序,用于创建逼真的裸体照片

    AI Clothes Remover

    AI Clothes Remover

    用于从照片中去除衣服的在线人工智能工具。

    Undress AI Tool

    Undress AI Tool

    免费脱衣服图片

    Clothoff.io

    Clothoff.io

    AI脱衣机

    AI Hentai Generator

    AI Hentai Generator

    免费生成ai无尽的。

    热工具

    记事本++7.3.1

    记事本++7.3.1

    好用且免费的代码编辑器

    SublimeText3汉化版

    SublimeText3汉化版

    中文版,非常好用

    禅工作室 13.0.1

    禅工作室 13.0.1

    功能强大的PHP集成开发环境

    Dreamweaver CS6

    Dreamweaver CS6

    视觉化网页开发工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神级代码编辑软件(SublimeText3)

    适用于 Ubuntu 和 Debian 的 PHP 8.4 安装和升级指南 适用于 Ubuntu 和 Debian 的 PHP 8.4 安装和升级指南 Dec 24, 2024 pm 04:42 PM

    PHP 8.4 带来了多项新功能、安全性改进和性能改进,同时弃用和删除了大量功能。 本指南介绍了如何在 Ubuntu、Debian 或其衍生版本上安装 PHP 8.4 或升级到 PHP 8.4

    如何设置 Visual Studio Code (VS Code) 进行 PHP 开发 如何设置 Visual Studio Code (VS Code) 进行 PHP 开发 Dec 20, 2024 am 11:31 AM

    Visual Studio Code,也称为 VS Code,是一个免费的源代码编辑器 - 或集成开发环境 (IDE) - 可用于所有主要操作系统。 VS Code 拥有针对多种编程语言的大量扩展,可以轻松编写

    我后悔之前不知道的 7 个 PHP 函数 我后悔之前不知道的 7 个 PHP 函数 Nov 13, 2024 am 09:42 AM

    如果您是一位经验丰富的 PHP 开发人员,您可能会感觉您已经在那里并且已经完成了。您已经开发了大量的应用程序,调试了数百万行代码,并调整了一堆脚本来实现操作

    您如何在PHP中解析和处理HTML/XML? 您如何在PHP中解析和处理HTML/XML? Feb 07, 2025 am 11:57 AM

    本教程演示了如何使用PHP有效地处理XML文档。 XML(可扩展的标记语言)是一种用于人类可读性和机器解析的多功能文本标记语言。它通常用于数据存储

    在PHP API中说明JSON Web令牌(JWT)及其用例。 在PHP API中说明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

    JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

    php程序在字符串中计数元音 php程序在字符串中计数元音 Feb 07, 2025 pm 12:12 PM

    字符串是由字符组成的序列,包括字母、数字和符号。本教程将学习如何使用不同的方法在PHP中计算给定字符串中元音的数量。英语中的元音是a、e、i、o、u,它们可以是大写或小写。 什么是元音? 元音是代表特定语音的字母字符。英语中共有五个元音,包括大写和小写: a, e, i, o, u 示例 1 输入:字符串 = "Tutorialspoint" 输出:6 解释 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。总共有 6 个元

    解释PHP中的晚期静态绑定(静态::)。 解释PHP中的晚期静态绑定(静态::)。 Apr 03, 2025 am 12:04 AM

    静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

    什么是PHP魔术方法(__ -construct,__destruct,__call,__get,__ set等)并提供用例? 什么是PHP魔术方法(__ -construct,__destruct,__call,__get,__ set等)并提供用例? Apr 03, 2025 am 12:03 AM

    PHP的魔法方法有哪些?PHP的魔法方法包括:1.\_\_construct,用于初始化对象;2.\_\_destruct,用于清理资源;3.\_\_call,处理不存在的方法调用;4.\_\_get,实现动态属性访问;5.\_\_set,实现动态属性设置。这些方法在特定情况下自动调用,提升代码的灵活性和效率。

    See all articles