목차
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 기반 앱

    AI Clothes Remover

    AI Clothes Remover

    사진에서 옷을 제거하는 온라인 AI 도구입니다.

    Undress AI Tool

    Undress AI Tool

    무료로 이미지를 벗다

    Clothoff.io

    Clothoff.io

    AI 옷 제거제

    AI Hentai Generator

    AI Hentai Generator

    AI Hentai를 무료로 생성하십시오.

    인기 기사

    R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
    3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. 최고의 그래픽 설정
    3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
    3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
    WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
    3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

    뜨거운 도구

    메모장++7.3.1

    메모장++7.3.1

    사용하기 쉬운 무료 코드 편집기

    SublimeText3 중국어 버전

    SublimeText3 중국어 버전

    중국어 버전, 사용하기 매우 쉽습니다.

    스튜디오 13.0.1 보내기

    스튜디오 13.0.1 보내기

    강력한 PHP 통합 개발 환경

    드림위버 CS6

    드림위버 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로 업그레이드하는 방법을 설명합니다.

    CakePHP 데이터베이스 작업 CakePHP 데이터베이스 작업 Sep 10, 2024 pm 05:25 PM

    CakePHP에서 데이터베이스 작업은 매우 쉽습니다. 이번 장에서는 CRUD(생성, 읽기, 업데이트, 삭제) 작업을 이해하겠습니다.

    CakePHP 날짜 및 시간 CakePHP 날짜 및 시간 Sep 10, 2024 pm 05:27 PM

    cakephp4에서 날짜와 시간을 다루기 위해 사용 가능한 FrozenTime 클래스를 활용하겠습니다.

    CakePHP 파일 업로드 CakePHP 파일 업로드 Sep 10, 2024 pm 05:27 PM

    파일 업로드 작업을 위해 양식 도우미를 사용할 것입니다. 다음은 파일 업로드의 예입니다.

    CakePHP 라우팅 CakePHP 라우팅 Sep 10, 2024 pm 05:25 PM

    이번 장에서는 라우팅과 관련된 다음과 같은 주제를 학습하겠습니다.

    CakePHP 토론 CakePHP 토론 Sep 10, 2024 pm 05:28 PM

    CakePHP는 PHP용 오픈 소스 프레임워크입니다. 이는 애플리케이션을 훨씬 쉽게 개발, 배포 및 유지 관리할 수 있도록 하기 위한 것입니다. CakePHP는 강력하고 이해하기 쉬운 MVC와 유사한 아키텍처를 기반으로 합니다. 모델, 뷰 및 컨트롤러 gu

    CakePHP 유효성 검사기 만들기 CakePHP 유효성 검사기 만들기 Sep 10, 2024 pm 05:26 PM

    컨트롤러에 다음 두 줄을 추가하면 유효성 검사기를 만들 수 있습니다.

    CakePHP 로깅 CakePHP 로깅 Sep 10, 2024 pm 05:26 PM

    CakePHP에 로그인하는 것은 매우 쉬운 작업입니다. 한 가지 기능만 사용하면 됩니다. cronjob과 같은 백그라운드 프로세스에 대해 오류, 예외, 사용자 활동, 사용자가 취한 조치를 기록할 수 있습니다. CakePHP에 데이터를 기록하는 것은 쉽습니다. log() 함수는 다음과 같습니다.

    See all articles