PHP自動載入機制

2021-08-01 21:51:15 字數 3365 閱讀 1691

自動載入機制的主要執行過程:

(1) 檢查執行器全域性變數函式指標autoload_func是否為null。

(2) 如果autoload_func==null, 則查詢系統中是否定義有__autoload()函式,如果沒有,則報告錯誤並退出。

(3) 如果定義了__autoload()函式,則執行__autoload()嘗試載入類,並返回載入結果。

(4) 如果autoload_func不為null,則直接執行autoload_func指標指向的函式用來載入類。注意此時並不檢查__autoload()函式是否定義。

根據以上定義,自動載入機制在實現的時候分為兩大類:__autoload,spl autoload

(1)最簡單的檔案引入方式require/include:

在使用php的oo模式開發系統時,通常大家習慣上將每個類的實現都存放在乙個單獨的檔案裡,這樣會很容易實現對類進行復用,同時將來維護時也很便利。在乙個指令碼檔案中我們需要使用到其他檔案中的類時,最簡單的做法就是使用require/include將類檔案引入。但時當我們需要用到大量的類時,就不得不寫很多的require/include語句,同時也可能會造成個別類檔案的引入遺漏了。

php5為這個問題提供了乙個解決方案,這就是類的自動載入機制。autoload機制可以使得php程式有可能在使用類時才自動包含類檔案,而不是一開始就將所有的類檔案include進來,這種機制也稱為lazy loading。

(2)__autoload

void

__autoload( string$class)          你可以通過定義這個函式來啟用類的自動載入。

<?php

/*下面是使用autoload機制載入dog類的例子:*/根據註冊的先後,如果在第乙個註冊的方法或函式裡載入了類檔案,就不會再執行第二個被註冊的類的方法或函式。反之就會執行第二個被註冊的類的方法或函式。

function __autoload($classname)

$d=new dog('哈巴狗',20);

?>

從這個例子中,我們可以看出 __autoload至少要做三件事情,第一件事是根據類名確定類檔名,第二件事是確定類檔案所在的磁碟路徑(在我們的例子是最簡單的情況,類與呼叫它們的 php程式檔案在同乙個資料夾下),第三件事是將類從磁碟檔案中載入到系統中。第三步最簡單,只需要使用include/require即可。要實現第一 步,第二步的功能,必須在開發時約定類名與磁碟檔案的對映方法,只有這樣我們才能根據類名找到它對應的磁碟檔案。那麼這表明:__autoload()函式的實現中最重要的是類名與實際的磁碟檔案對映規則的實現。

那麼問題就來了,如果有大量開發人員參與乙個專案類庫的開發,或者需要引入第三方類庫,這會導致類名與實際的磁碟檔案對映規則有很多種,那麼__autoload函式為了實現類檔案的自動載入,就需要一一實現這些規則,並且還要進行大量的if-eles判斷,這造成了__autoload函式的臃腫,效率低下,維護也造成不便。

(3)spl_autoload,spl_autoload_call  (手動呼叫)

spl autoload機制能夠很好的解決上述問題。 spl autoload機制的實現是通過將函式指標autoload_func指向自己實現的具有自動裝載功能的函式來實現的。spl有兩個不同的函式 spl_autoload, spl_autoload_call,通過將autoload_func指向這兩個不同的函式位址來實現不同的自動載入機制。

1. spl_autoload:(spl實現的預設的自動載入函式)

void

spl_autoload( string$class_name[,string$file_extensions] )

它可以接收兩個引數,第乙個引數是$class_name,表示類名,第二個參 數$file_extensions是可選的,表示類檔案的副檔名,多個副檔名用逗號隔開

在預設情況下,本函式先將類名轉換成小寫,再在小寫的類名後加上 .inc 或 .php 的副檔名作為檔名,然後在所有的包含路徑(include paths)中檢查是否存在該檔案。

常見的用法是和set_include_path,sql_autoload_extensions搭配使用

/*例子如下:mvc中實現控制器類的載入*/

public function load_controller($controller)

}   

2. spl_autoload_call

如果需要多條 autoload 函式,spl_autoload_register()滿足了此類需求。 它實際上建立了 autoload 函式的佇列,按定義時的順序逐個執行。相比之下,    __autoload()只可以定義一次。

void

spl_autoload_call( string$class_name)

可以直接在程式中手動呼叫此函式來使用所有已註冊的__autoload函式裝載類或介面。

在使用spl_aulotoload_call後,系統會根據autoload函式佇列中函式註冊的先後,如果在第乙個註冊的方法或函式裡載入了類檔案,就不會再執行第二個被註冊的類的方法或函式。反之就會執行第二個被註冊的類的方法或函式。

注意:如果在你的程式中已經實現了__autoload()

函式,它必須顯式註冊到__autoload()

佇列中。因為spl_autoload_register()函式會將zend engine中的__autoload()

函式取代為spl_autoload()

或spl_autoload_call()

。 (4) autoload效率問題及對策

使 用autoload機制時,很多人的第一反應就是使用autoload會降低系統效率,甚至有人乾脆提議為了效率不要使用autoload。在我們了解了 autoload實現的原理後,我們知道autoload機制本身並不是影響系統效率的原因,甚至它還有可能提高系統效率,因為它不會將不需要的類載入到 系統中。

那麼為什麼很多人都有乙個使用autoload會降低系統效率的印象呢?實際上,影響autoload機制效率本身恰恰是使用者設計的自動載入函式。如果它 不能高效的將類名與實際的磁碟檔案(注意,這裡指實際的磁碟檔案,而不僅僅是檔名)對應起來,系統將不得不做大量的檔案是否存在(需要在每個 include path中包含的路徑中去尋找)的判斷,而判斷檔案是否存在需要做磁碟i/o操作,眾所周知磁碟i/o操作的效率很低,因此這才是使得autoload機 制效率降低的罪魁禍首!

因此,我們在系統設計時,需要定義一套清晰的將類名與實際磁碟檔案對映的機制。這個規則越簡單越明確,autoload機制的效率就越高。







php 自動載入機制

一 基礎了解。1 php引入檔案使用include與require,這兩個的區別在於,include可以在 執行過程中再引入,而require是需要在 執行前就進行引入操作。2 命名空間。引入命名空間的作用是為了規避掉因為重名而引發的混亂與錯誤。可以把命名空間理解為乙個箱子,不同的箱子都可以有蘋果,...

PHP的自動載入機制

原因 我們在寫php 的時候,總會遇到這種情況 a.php需要引入 php才能正常執行 結構比較小的話,通常我們都是直接通過 include 或者 require 直接引入,如果需要引入的檔案不多的話,還可以接受,但是如果引入的檔案達到幾十個以上,再用 include 和 require 就顯得比較...

php的自動載入機制

一 php中實現自動載入的方法 使用require,include,require once,include once手工進行載入。使用 autoload來進行自動載入 使用spl的autoload來實現自動載入 手工載入的實現 當需要載入的檔案很少的時候我們可以使用第乙個來完成。這樣做很簡單也沒問...