關於php的自動載入機制的了解認知

2021-09-13 15:09:37 字數 2993 閱讀 8278

如果你對命名空間不熟悉,可移步:

以前的時候,我們可以將多個類寫在同乙個php檔案中,他們之間可以直接相互使用,慢慢的,隨著專案的擴大,我們發覺這種方法並不規範,於是慢慢轉變成了乙個類就是乙個檔案,在需要引用其他類時,我們會使用require或者include對其進行引入,這種手動的方式在檔案少的時候確實沒問題,但專案的類越來越多,要寫的require/include也越來越多。phper們覺得這種方式真的太傻了。於是開始想用一種方式可以直接載入,而不用再寫那麼多的require/include

舉個例子:

//檔案 b.php

<?php

class b

}?>

//檔案 a.php

<?php

class a

}function __autoload($classname)

$a_object = new a();

$a_oject->test();

?>

命令列輸入:#php a.php

輸出: 「我是class b中的方法執行結果「

這裡我們可以看出,我們實現了__autonload()這個函式,這個函式在php找不到類的時候會自動的呼叫。也就是說當b這個類沒有找到的時候,它會執行__autoload()方法,引數一則是該類名,因此,我們只需要在這個方法裡面對這個類進行引入即可。

你可以看到,我們就寫了個 require $classname.'.php',即引入當前目錄的該類名檔案,但是乙個正常的專案是會有多個目錄的,那麼裡面的實現邏輯可就不能那麼簡單了,必須得帶上目錄才行。

那麼我們也就需要有乙個對映關係,用來找那個類具體所在的目錄名。這個對映關係大家可以思考一下如何去實現。

樓上的兄弟是很原始的一種載入方式了。現在我們學一種比較高階的。即:spl的自動載入。

那麼我們得先來理解幾個有關的函式:

2.2.1  spl_autoload_register()穿越

將函式註冊到spl __autoload函式佇列中。如果該佇列中的函式尚未啟用,則啟用它們。

如果在你的程式中已經實現了__autoload()函式,它必須顯式註冊到__autoload()佇列中。因為spl_autoload_register()函式會將zend engine中的__autoload()函式取代為spl_autoload()或spl_autoload_call()。

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

我們可以簡單理解成這是用來註冊實現__autoload的函式

2.2.2  spl_autoload()穿越

本函式提供了__autoload()的乙個預設實現。如果不使用任何引數呼叫 spl_autoload_register() 函式,則以後在進行 __autoload() 呼叫時會自動使用此函式。

2.2.3  spl_autoload_functions()穿越

獲取所有已註冊的 __autoload() 函式。

2.2.4 spl_autoload_call()穿越

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

假設我們自定義了乙個autoload($class)。

那麼我們需要去註冊使用這個東西:spl_autoload_register('autoload'), 那麼這個函式就被註冊到了 autoload_functions這個hashmap中了,autoload_function是乙個全域性變數,用來存放註冊的autoload方法,

這些方法又需要使用spl_autoload_call()去主動呼叫

當我們使用了spl_autoload_register後,會有乙個autoload_func指標,用來指向我們自定義的autoload方法。

因此,如果沒有使用spl_autoload_register,則autoload_func為null,那麼autoload的機制可以理解為如下:

檢查執行器全域性變數函式指標autoload_func是否是null;

如果 autoload_func==null ,則查詢系統是否定義 __autoload() 函式,如果定義了,則執行並返回載入結果。如果沒有定義,則報錯並退出;

如果 autoload_func 不等於null,則直接執行 autoload_func 指向的函式載入類,此時並不檢查 __autoload() 函式是否定義。

我們可以簡單這麼寫:

class  mcphp 

//獲取基礎目錄名

$baseclasspath = \str_replace('\\', ds, $class) . '.php';

//下面可以新增多個目錄

$libs = array(

);foreach ($libs as $lib) ";

return;}}

}}

那麼,此時命名空間又有啥用呢?即使沒有對應目錄哪又如何。

其實命名空間的作用之一是在於解決同名類衝突或者函式名衝突等。,而且通過命名空間我們可以取到我們真正想用的類。實際上他是一種規範,我們盡量讓命名空間的命名和目錄有所聯絡,可以讓**看起來更加的規範化。但是他和自動載入並沒有多大關係,即使我們不使用自動載入,單純的require/include也是可以使用命名空間的。如果不信的話你可以在框架上故意修改命名空間的名稱和目錄不一致,即使改了,也不會影響自動載入,

PHP的自動載入機制

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

php的自動載入機制

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

PHP自動載入機制

自動載入機制的主要執行過程 1 檢查執行器全域性變數函式指標autoload func是否為null。2 如果autoload func null,則查詢系統中是否定義有 autoload 函式,如果沒有,則報告錯誤並退出。3 如果定義了 autoload 函式,則執行 autoload 嘗試載入類...