博主信息
Victor的博客
博文
35
粉絲
0
評論
0
訪問量
8522
積分:0
P豆:78

PHP命名空間分級管理及trait類的使用場景--2019年10月10日

2019年10月16日 02:15:44閱讀數:430博客 / Victor的博客 / PHP

1、寫一個分級的命名空間,并實現類的自動加載

2、寫一個trait類,理解它的功能與使用場景

【1】命名空間分級管理與類的自動加載

        PHP 作為一種腳本語言,不存在程序入口,在開發中,各種初始化、業務流程都分散在各個不同的文件中,如果引用不同文件中的類,需要一堆 include 函數包含一大堆文件,這即顯得笨拙,也不易于后期維護,因此,需要使用自動加載機制來完成這種引用。

實現自動加載管理,首先需要遵循相應的一些規則(主要是PSR-4):

  • 廢除了PSR-0中_就是目錄分割符的寫法,_下劃線在完全限定類名中是沒有特殊含義了。

  • 類文件名要以 .php 結尾。

  • 一個類存放在一個同名的文件中;

  • 類名必須要和對應的文件名要一模一樣,大小寫也要一模一樣。

  • 命名空間的分層 一定要與 類文件的目錄分層 完全一致。  

最終實現將命名空間\類這樣的類名,給轉換成目錄名/類名.php這樣的路徑,并返回完整路徑。

使用自動加載需注意的細節:

  • ____autoload函數馬上要在7.2版本的PHP中棄用了,應使用spl_autoload_register()實現,它的好處是可以自定義多個autoloader;

  • 包含spl_autoload_register()的自動加載文件,必須放在根空間下(對應系統的root目錄),這樣才可以管理根空間內所有的類文件;如果去加載根空間以外的類文件是會報錯的。

  • 類的自動加載不可用于PHP的CLI交互模式;

  • 類的查找順序:優先查找手動include或require進來的類,查找不到的情況下再采用類的自動加載機制;

  • 如果類名比如被用于call_user_func(),則它可能包含一些危險的字符,比如 ../。 建議在這樣的函數中不要使用用戶的輸入,起碼需要驗證下輸入。

  • 自動加載并不是萬無一失的,有些特殊場景需單獨考慮。

實例說明    (命名空間--->目錄結構---->目錄下類文件的對應關系):

根空間\                    -------->    ROOT目錄                             (Autoloader.php)

\inc\Controller       -------->    ROOT/inc/Controller目錄    (Contrl.php)

\inc\model               -------->    ROOT/inc/model目錄        (Marticle.php , Mcard.php)

\inc\view                  -------->    ROOT/inc/view目錄            (Varticle.php , Vcard.php)

實例代碼:

實例
<?php

class Autoloader {
	public static function register() {
		spl_autoload_register(function ($class) {
			$file = str_replace('\\', DIRECTORY_SEPARATOR, $class); 
			$file = __DIR__ . '/' . $file . '.php';
			if (file_exists($file)) {
				include $file;
				return true;
			}
			return false;
		});
	}
}
Autoloader::register();

?>
運行實例 ?
點擊 "運行實例" 按鈕查看在線實例
實例
<?php

namespace _1010;

include 'Autoloader.php';

$a = new \inc\Controller\Contrl();
$b = new \inc\model\Marticle();
$c = new \inc\model\Mcard();
$d = new \inc\view\Varticle();
$e = new \inc\view\Vcard();

?>
運行實例 ?
點擊 "運行實例" 按鈕查看在線實例

【2】Trait 特性

Trait是為減少單繼承語言限制,來達到多繼承的效果。它可以混入不同結構獨立的類中復用方法集。使用關鍵字“Trait”來聲明,類包含的特性,Trait都支持,但不能通過自身實例化對象。

對于重名屬性和方法,優先順序是:當前類成員優先級 > Trait內成員優先級 > 所繼承的父類內的成員優先級。

Trait可看作模塊化的零部件,可在單個類中,用use引入多個,有成員屬性沖突時,使用insteadof和as操作符解決。

以下代碼演示一個Trait嵌套和混入的使用場景:

實例
<?php

trait Demo1_trait {
	function method1() {
		echo 'Demo1_trait的方法:method1()';
	}
}

trait Demo2_trait {
	use Demo1_trait;
	function method2() {
		echo 'Demo2_trait的方法:method2()';
	}
}

class Demo {
	use Demo2_trait;
}

$obj = new Demo();
$obj->method1();
$obj->method2();

?>
運行實例 ?
點擊 "運行實例" 按鈕查看在線實例

總結:

1、使用自動加載的好處:

  • 擺脫長長的 include() 與 require();

  • 使用類時才會引入文件,實現了 lazy loading;

  • 無需知道類的實際文件地址,實現了邏輯和實體文件的分離;

  • 相比于絕對路徑引入類的文件路徑,自動加載機制在當類庫目錄名或者文件名需要更改的時候,所有include了這個文件的php文件不需要隨著修改,這避免了加大源代碼目錄結構重構的負擔;

  • 相比于在php.ini中的include_path引入類的文件路徑,自動加載的機制可以節省很多性能問題;

  • 雖然性能和__FILE__魔術方法引入相對類路徑的性能相近,但是自動加載機制可以防止或減少require_once,include_once在文件各處的隨意使用,也不用計較類與類之間相互依賴的引入順序;

  • 可以通過帶命名空間的引用和別名的方法,解決多個類重名或者同個app目錄下及子目錄下重名。

2、Trait就像實現某類功能的組件,可以更靈活的復用自定義功能,而不必局限與繼承關系上。




批改狀態:合格

老師批語:總結的非常到位

全部評論

文明上網理性發言,請遵守新聞評論服務協議

條評論
暫無評論暫無評論!
  • 白小姐救世民彩图2019