【PHP系列】PHP推薦標準之PSR-4,自動加載器策略

接上回的繼續說,上回說到PSR-3日誌記錄器接口,這回咱們來講說PSR的最後一個標準,PSR-4,自動加載器策略。php

原因

自動加載器策略是指,在運行時按需查找PHP類、接口或性狀,並將其載入PHP解釋器。web

支持PSR-4自動加載器標準的PHP組件和框架,使用同一個自動加載器就能找到相關代碼,而後將其載入PHP解釋器。app

怎麼來理解呢,你可能看PHP代碼的時候常常會看到下面的代碼框架

<?php
include 'path/to/file1.php';
include 'path/to/file2.php';
include 'path/to/file3.php';

若是須要引入一百個,一千個PHP腳本,include()函數就不能勝任了。有了自動加載器,咱們就無需這樣引入文件,自動加載器策略能找到PHP類、接口或性狀,而後在運行時按需將其載入PHP解釋器。函數

大多數現代的PHP組件和框架都符合PSR-4規範,若是你要本身編寫並分發PHP組件,確保你的組件也符合PSR-4規範。ui

PSR-4

一、The term 「class」 refers to classes, interfaces, traits, and other similar structures.this

二、A fully qualified class name has the following form:spa

 \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>

The fully qualified class name MUST have a top-level namespace name, also known as a 「vendor namespace」.日誌

The fully qualified class name MAY have one or more sub-namespace names.code

The fully qualified class name MUST have a terminating class name.

Underscores have no special meaning in any portion of the fully qualified class name.

Alphabetic(按字母排序的) characters in the fully qualified class name MAY be any combination of lower case and upper case.

All class names MUST be referenced in a case-sensitive fashion.

三、When loading a file that corresponds to a fully qualified class name …(加載完整路徑類名)

A contiguous series of one or more leading namespace and sub-namespace names, not including the leading namespace separator, in the fully qualified class name (a 「namespace prefix」) corresponds to at least one 「base directory」.

The contiguous sub-namespace names after the 「namespace prefix」 correspond to a subdirectory within a 「base directory」, in which the namespace separators represent directory separators. The subdirectory name MUST match the case of the sub-namespace names.

The terminating class name corresponds to a file name ending in .php. The file name MUST match the case of the terminating class name.

四、Autoloader implementations MUST NOT throw exceptions, MUST NOT raise errors of any level, and SHOULD NOT return a value.

例子

    FULLY QUALIFIED CLASS NAME     NAMESPACE PREFIX     BASE DIRECTORY     RESULTING FILE PATH
    \Acme\Log\Writer\File_Writer     Acme\Log\Writer     ./acme-log-writer/lib/     ./acme-log-writer/lib/File_Writer.php
    \Aura\Web\Response\Status     Aura\Web     /path/to/aura-web/src/     /path/to/aura-web/src/Response/Status.php
    \Symfony\Core\Request     Symfony\Core     ./vendor/Symfony/Core/     ./vendor/Symfony/Core/Request.php
    \Zend\Acl     Zend     /usr/includes/Zend/     /usr/includes/Zend/Acl.php

PSR-4的精髓是把命名空間的前綴和文件系統中的目錄對應起來。例如,我能夠告訴PHP,\Feng\YePHP命名空間中的類、接口和性狀在物理文件系統的src/目錄中,這樣PHP就知道,前綴爲\Feng\YePHP的命名空間中的類、接口和性狀對應於src/目錄裏的目錄和文件。

如何編寫

<?php
/**
 * An example of a project-specific implementation.
 * 
 * After registering this autoload function with SPL, the following line
 * would cause the function to attempt to load the \Foo\Bar\Baz\Qux class
 * from /path/to/project/src/Baz/Qux.php:
 * 
 *      new \Foo\Bar\Baz\Qux;
 *      
 * @param string $class The fully-qualified class name.
 * @return void
 */
spl_autoload_register(function ($class) {

    // project-specific namespace prefix
    $prefix = 'Foo\\Bar\\';

    // base directory for the namespace prefix
    $base_dir = __DIR__ . '/src/';

    // does the class use the namespace prefix?
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        // no, move to the next registered autoloader
        return;
    }

    // get the relative class name
    $relative_class = substr($class, $len);

    // replace the namespace prefix with the base directory, replace namespace
    // separators with directory separators in the relative class name, append
    // with .php
    $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';

    // if the file exists, require it
    if (file_exists($file)) {
        require $file;
    }
});

複製以上代碼,將其粘貼到你的應用中,而後修改變量$prefix和$base_dir的值,這樣你就能夠擁有一個可用的PSR-4自動加載器了。

可是你大可沒必要這麼作,由於咱們可使用依賴管理器Composer自動生成的PSR-4自動加載器。咱們會在後續的博文中說起這個Composer。 

相關文章
相關標籤/搜索