php 自動載入規範 psr0 psr4 詳解
阿新 • • 發佈:2019-01-22
1.psr0 這是個啥東西呢,這是一個標準。
一個實現自動載入類的標準。
在這之前你需要先了解__autoload 和spl_autoload_register這兩個方法。
為什麼要實現這個標準呢?
如果整個專案是自己寫的不需要任何其他人的程式碼,那好。你想怎麼定義這個標準就怎麼定義。可是當你需要呼叫第三方的類庫的時候。
就會出現問題,因為可能你們兩個自動載入類的標準不同所以,自動載入類是需要一個標準的。
介紹一下這個標準:
規範:
- 完全限定的名稱空間和類必須具有以下結構
\<Vendor Name>\(<Namespace>\)*<Class Name>
- 每個名稱空間必須具有頂級名稱空間(“供應商名稱”)。
- 每個名稱空間可以擁有儘可能多的子名稱空間。
DIRECTORY_SEPARATOR
從檔案系統載入時,每個名稱空間分隔符都將轉換為一個。_
CLASS NAME中的每個字元都轉換為aDIRECTORY_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更加的完善。
官方規範:
-
完全限定的類名必須具有頂級名稱空間名稱,也稱為“供應商名稱空間”。
-
完全限定類名稱可以有一個或多個子名稱空間名稱。
-
完全限定的類名必須有終止類名。
-
下劃線在完全限定類名的任何部分都沒有特殊意義。
-
完全限定類名稱中的字母字元可以是小寫和大寫字母的任何組合。
-
所有類名必須以區分大小寫的方式引用。
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 |
可能你看完很懵逼,我也有點懵逼。待我看看原始碼,如果理解了再來補充吧!