php中spl_autoload詳解
SPL有兩個(gè)不同的函數(shù) spl_autoload, spl_autoload_call,通過(guò)將autoload_func指向這兩個(gè)不同的函數(shù)地址來(lái)實(shí)現(xiàn)不同的自動(dòng)加載機(jī)制。
spl_autoload 是SPL實(shí)現(xiàn)的默認(rèn)的自動(dòng)加載函數(shù),它的功能比較簡(jiǎn)單。它可以接收兩個(gè)參數(shù),第一個(gè)參數(shù)是$class_name,表示類(lèi)名,第二個(gè)參 數(shù)$file_extensions是可選的,表示類(lèi)文件的擴(kuò)展名" title="擴(kuò)展名">擴(kuò)展名,可以在$file_extensions中指定多個(gè)擴(kuò)展名" title="擴(kuò)展名">擴(kuò)展名,護(hù)展名之間用分號(hào)隔開(kāi)即 可;如果不指定的話,它將使用默認(rèn)的擴(kuò)展名" title="擴(kuò)展名">擴(kuò)展名.inc或.php。spl_autoload首先將$class_name變?yōu)樾?xiě),然后在所有的 include path中搜索$class_name.inc或$class_name.php文件(如果不指定$file_extensions參數(shù)的話),如果找 到,就加載該類(lèi)文件。你可以手動(dòng)使用spl_autoload(”P(pán)erson”, “.class.php”)來(lái)加載Person類(lèi)。實(shí)際上,它跟require/include差不多,不同的它可以指定多個(gè)擴(kuò)展名" title="擴(kuò)展名">擴(kuò)展名。
怎 樣讓spl_autoload自動(dòng)起作用呢,也就是將autoload_func指向spl_autoload?答案是使用 spl_autoload_register函數(shù)。在PHP腳本中第一次調(diào)用spl_autoload_register()時(shí)不使用任何參數(shù),就可以將 autoload_func指向spl_autoload。
通過(guò)上面的說(shuō)明我們知道,spl_autoload的功能比較簡(jiǎn)單,而且它是在SPL擴(kuò)展中實(shí)現(xiàn)的,我們無(wú)法擴(kuò)充它的功能。如果想實(shí)現(xiàn)自己的更靈活的自動(dòng)加載機(jī)制怎么辦呢?這時(shí),spl_autoload_call函數(shù)閃亮登場(chǎng)了。
我 們先看一下spl_autoload_call的實(shí)現(xiàn)有何奇妙之處。在SPL模塊內(nèi)部,有一個(gè)全局變量autoload_functions,它本質(zhì)上是 一個(gè)HashTable,不過(guò)我們可以將其簡(jiǎn)單的看作一個(gè)鏈表,鏈表中的每一個(gè)元素都是一個(gè)函數(shù)指針,指向一個(gè)具有自動(dòng)加載類(lèi)功能的函數(shù)。 spl_autoload_call本身的實(shí)現(xiàn)很簡(jiǎn)單,只是簡(jiǎn)單的按順序執(zhí)行這個(gè)鏈表中每個(gè)函數(shù),在每個(gè)函數(shù)執(zhí)行完成后都判斷一次需要的類(lèi)是否已經(jīng)加載, 如果加載成功就直接返回,不再繼續(xù)執(zhí)行鏈表中的其它函數(shù)。如果這個(gè)鏈表中所有的函數(shù)都執(zhí)行完成后類(lèi)還沒(méi)有加載,spl_autoload_call就直接 退出,并不向用戶(hù)報(bào)告錯(cuò)誤。因此,使用了autoload機(jī)制,并不能保證類(lèi)就一定能正確的自動(dòng)加載,關(guān)鍵還是要看你的自動(dòng)加載函數(shù)如何實(shí)現(xiàn)。
在php5中的標(biāo)準(zhǔn)庫(kù)方法spl_autoload相當(dāng)于實(shí)現(xiàn)自己的__autoload
<?php
function __autoload($classname){
if(is_file($classname.'.php'){
include $classname.'.php';
} elseif(is_file($classname.'.inc'){
include $classname.'.inc';
}
}
它會(huì)在注冊(cè)目錄下自動(dòng)尋找與$classname同名的.php/.inc文件。當(dāng)然,你也可以指定特定類(lèi)型的文件,方法是注冊(cè)擴(kuò)展名
<?php
spl_autoload_extensions('.php,.inc,.some');
這樣,它也會(huì)搜索.some文件。默認(rèn),php是不會(huì)啟動(dòng)spl_autoload的,那么怎樣才能自動(dòng)讓spl_autoload生效呢呢?方法是
<?php
spl_autoload_register();
spl_autoload_register有一個(gè)$callback參數(shù),如果不指定,它就會(huì)自動(dòng)注冊(cè)spl_autoload,為了能搜尋更多的自動(dòng)加載目錄,可以在這些代碼前面設(shè)置自動(dòng)加載目錄
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . 'some/path' . DIRECTORY_SEPARATOR);
這樣,當(dāng)php找不到指定的類(lèi)時(shí),就會(huì)在set_include_path指定的目錄下尋找。
這些方法常用在php框架中。比如把上面的介紹串連起來(lái):
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . 'some/path' . DIRECTORY_SEPARATOR);
spl_autoload_extensions('.php,.inc,.some');
spl_autoload_register();
當(dāng)你要加載some/path下面的classA類(lèi)時(shí),它會(huì)在目錄下尋找classa.php或classa.inc或classa.some,這樣你就可以放心地運(yùn)用new classA或extends classA
<?php
ClassB extends ClassA {
// code..
}
$a = new ClassA;
$b = new ClassB;
- Laravel訪問(wèn)出錯(cuò)提示:`Warning: require(/vendor/autoload.php): failed to open stream: No such file or di解決方法
- PHP自動(dòng)加載autoload和命名空間的應(yīng)用小結(jié)
- PHP中spl_autoload_register()函數(shù)用法實(shí)例詳解
- PHP中__autoload和Smarty沖突的簡(jiǎn)單解決方法
- CodeIgniter配置之a(chǎn)utoload.php自動(dòng)加載用法分析
- PHP autoload機(jī)制案例詳解
相關(guān)文章
PHP ob緩存以及ob函數(shù)原理實(shí)例解析
這篇文章主要介紹了PHP ob緩存以及ob函數(shù)原理實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
PHP如何實(shí)現(xiàn)給頁(yè)面設(shè)置獨(dú)立訪問(wèn)密碼
這篇文章主要為大家詳細(xì)介紹了PHP如何實(shí)現(xiàn)給頁(yè)面設(shè)置獨(dú)立訪問(wèn)密碼,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以了解下2024-03-03
PHP生成可點(diǎn)擊刷新的驗(yàn)證碼簡(jiǎn)單示例
這篇文章主要介紹了PHP生成可點(diǎn)擊刷新的驗(yàn)證碼,結(jié)合簡(jiǎn)單實(shí)例形式分析了php驗(yàn)證碼的實(shí)現(xiàn)與調(diào)用顯示方法,涉及js動(dòng)態(tài)調(diào)用驗(yàn)證碼php文件的相關(guān)技巧,需要的朋友可以參考下2016-05-05
PHP字典樹(shù)(Trie樹(shù))定義與實(shí)現(xiàn)方法示例
這篇文章主要介紹了PHP字典樹(shù)(Trie樹(shù))定義與實(shí)現(xiàn)方法,簡(jiǎn)單描述了字典樹(shù)的概念并結(jié)合實(shí)例形式分析了字典樹(shù)的定義與使用方法,需要的朋友可以參考下2017-10-10

