1. 程式人生 > >php 自動載入規範 psr0 psr4 詳解

php 自動載入規範 psr0 psr4 詳解

1.psr0  這是個啥東西呢,這是一個標準。

   一個實現自動載入類的標準。

   在這之前你需要先了解__autoload 和spl_autoload_register這兩個方法。

   為什麼要實現這個標準呢?

如果整個專案是自己寫的不需要任何其他人的程式碼,那好。你想怎麼定義這個標準就怎麼定義。可是當你需要呼叫第三方的類庫的時候。

就會出現問題,因為可能你們兩個自動載入類的標準不同所以,自動載入類是需要一個標準的。

介紹一下這個標準:

規範:

  • 完全限定的名稱空間和類必須具有以下結構 \<Vendor Name>\(<Namespace>\)*<Class Name>
  • 每個名稱空間必須具有頂級名稱空間(“供應商名稱”)。
  • 每個名稱空間可以擁有儘可能多的子名稱空間。
  • DIRECTORY_SEPARATOR從檔案系統載入時,每個名稱空間分隔符都將轉換為一個
  • _CLASS NAME中的每個字元都轉換為a DIRECTORY_SEPARATOR_字元在該名稱空間沒有任何特殊含義。
  • .php當從檔案系統載入時,完全限定名稱空間和類字尾
  • 供應商名稱,名稱空間和類名稱中的字母字元可以是小寫和大寫的任何組合。

具體實現:
<?php

function autoload($className)
{
    $className = ltrim($className, '\\');
    $fileName  = '';
    $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;
}
spl_autoload_register('autoload');
就是實現這個標準的程式碼。

當你要例項化一個類的時候會相應的載入這個類:

autoload("/dir1/dir2/class1");

autoload("/dir1/dir2/class1_class2");

載入的類為(也就是實際的物理路徑):

/dir1/dir2/class1.php

/dir1/dir2/class1/class2.php

總結:其實就是根據你要例項化的類的名字,按照一個標準,去找這個類具體是在哪裡,然後require它,這樣就實現了自動載入。

2.psr4 是啥和psr0 有啥區別呢?

就是psr0的補充,讓psr更加的完善。

官方規範:

  1. 完全限定的類名必須具有頂級名稱空間名稱,也稱為“供應商名稱空間”。

  2. 完全限定類名稱可以有一個或多個子名稱空間名稱。

  3. 完全限定的類名必須有終止類名。

  4. 下劃線在完全限定類名的任何部分都沒有特殊意義。

  5. 完全限定類名稱中的字母字元可以是小寫和大寫字母的任何組合。

  6. 所有類名必須以區分大小寫的方式引用。

例子:
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

可能你看完很懵逼,我也有點懵逼。待我看看原始碼,如果理解了再來補充吧!