PHP命名空間的自動加載

什麼是命名空間?

參考:http://php.net/manual/zh/language.namespaces.rationale.php
(PHP 5 >= 5.3.0, PHP 7)

什麼是命名空間?從廣義上來說,命名空間是一種封裝事物的方法。在很多地方都可以見到這種抽象概念。例如,在操作系統中目錄用來將相關文件分組,對於目錄中的文件來說,它就扮演了命名空間的角色。具體舉個例子,文件
foo.txt 可以同時在目錄/home/greg 和 /home/other 中存在,但在同一個目錄中不能存在兩個 foo.txt
文件。另外,在目錄 /home/greg 外訪問 foo.txt 文件時,我們必須將目錄名以及目錄分隔符放在文件名之前得到
/home/greg/foo.txt。這個原理應用到程序設計領域就是命名空間的概念。

在PHP中,命名空間用來解決在編寫類庫或應用程序時創建可重用的代碼如類或函數時碰到的兩類問題:

用戶編寫的代碼與PHP內部的類/函數/常量或第三方類/函數/常量之間的名字衝突。
爲很長的標識符名稱(通常是爲了緩解第一類問題而定義的)創建一個別名(或簡短)的名稱,提高源代碼的可讀性。 PHP
命名空間提供了一種將相關的類、函數和常量組合到一起的途徑。

未引入命名空間時的解決類衝突的做法

通過require 引入需要用到的類

src/Person.php

<?php

class Person
{
	protected $name;

	public function __construct($name)
	{
		$this->name = $name;
	}
}

src/Business.php

<?php
class Business
{
	protected $staff;

	public function __construct(Staff $staff)
	{
		$this->staff = $staff;
	}

	public function hire(Person $person)
	{
		$this->staff->add($person);
	}
}

src/Staff.php

<?php
class Staff
{
	protected $members = [];

	public function add(Person $person)
	{
		$this->members[] = $person;
	}
}
require 'src/Person.php';
require 'src/Business.php';
require 'src/Staff.php';

$liang = new Person('liang');

$staff = new Staff();

$business = new Business($staff);
$business->hire($liang);

var_dump($staff);

PHP的自動加載 spl_autoload_register

spl_autoload_register函數是實現自動加載未定義類功能的的重要方法。
自動加載就是我們new一個類時PHP會自動幫我們加載依賴的類。

參考http://php.net/manual/zh/function.spl-autoload-functions.php

上面的例子可以簡化成這樣

spl_autoload_register(function($classNmae){
	require 'src/' . $classNmae . '.php';
});

$liang = new Person('liang');

$staff = new Staff();

$business = new Business($staff);
$business->hire($liang);

var_dump($staff);

利用PSR4規範進行自動加載

什麼是PSR4規範

參考:https://www.php-fig.org/psr/psr-4/

PSR4描述了從文件路徑自動加載類的規範。

  1. 術語“類”指的是類,接口,特徵和其他類似結構。

  2. 完全限定的類名具有以下形式:

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

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

    3. 完全限定的類名可以具有一個或多個子命名空間名稱。

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

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

    6. 完全限定類名中的字母字符可以是小寫和大寫的任意組合。

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

  3. 當從完全限定類名載入文件時:

    1. 在完全限定類名中,連續的一個或幾個子命名空間構成的命名空間前綴(不包括頂級命名空間的分隔符),至少對應着至少一個基礎目錄。
    2. 在「命名空間前綴」後的連續子命名空間名稱對應一個「基礎目錄」下的子目錄,其中的命名 空間分隔符表示目錄分隔符。子目錄名稱必須和子命名空間名大小寫匹配;
    3. 終止類名對應一個以 .php 結尾的文件。文件名必須和終止類名大小寫匹配;
  4. 自動載入器的實現不可拋出任何異常,不可引發任何等級的錯誤;也不應返回值;
    psr4示例

利用composer完成自動加載

  1. 給src/Person.php src/Business.php src/Staff.php加上namespace liang
  2. 編寫composer.json文件
{
	"autoload":{
		"psr-4":{
			"liang\\" : "src/"
		}
	}
}

“liang\” : “src/” 根據psr4規範將命名空間liang 映射到 src路徑

  1. 執行 composer dump-autoload 命令
    會生成vendor目錄
    目錄結構

  2. 在sample.php中 require 'vendor/autoload.php' 即可利用psr4規範完成加載

sample.php

require 'vendor/autoload.php';

use liang\Person;
use liang\Staff;
use liang\Business;


$liang = new Person('liang');

$staff = new Staff();

$business = new Business($staff);
$business->hire($liang);

var_dump($staff);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章