php中autoload的用法總結(jié)
PHP中提供了Autoload來(lái)幫助我們方便的進(jìn)行文件的包含,但是autoload并非想象的那樣能夠處理所有的情況,今天就來(lái)記錄一下前幾天遇到的autoload存在的一些問(wèn)題。
為什么要使用 Autoload
在PHP中使用類時(shí),我們必須在使用前加載進(jìn)來(lái),不管是通過(guò) require 的方式還是 include 的方式,但是會(huì)有兩個(gè)問(wèn)題影響我們做出加載的決定。
首先是不知道這個(gè)類文件存放在什么地方,另外一個(gè)就是不知道什么時(shí)候需要用到這個(gè)文件。特別是項(xiàng)目文件特別多時(shí),不可能每個(gè)文件都在開(kāi)始的部分寫(xiě)很長(zhǎng)一串的 require ….
在PHP5之后,我們可以通過(guò) __autoload來(lái)解決這個(gè)問(wèn)題。 而且在PHP5.1之后,還提供了 spl_autoload_register() 來(lái)提供更完善的加載機(jī)制。
通過(guò)閱讀了 Autoloading in PHP 這篇文章,我理解的 Autoload 的加載機(jī)制,當(dāng)通過(guò) new 來(lái)實(shí)例化一個(gè)類時(shí),PHP會(huì)通過(guò)定義的__autoload 函數(shù)加載相應(yīng)的文件,如果這個(gè)類文件使用了 extends 或者 implements 需要用到其他的類文件,php會(huì)重新運(yùn)行 autoload 去進(jìn)行類文件的查找和加載,如果發(fā)生了兩次對(duì)同一類文件的請(qǐng)求,就會(huì)報(bào)錯(cuò)。原文作者提供了三個(gè)很有趣的例子來(lái)說(shuō)明這個(gè)問(wèn)題,可以通過(guò) 這里 下載源碼查看。
一般情況下,有很多種方法來(lái)解決加載時(shí)到相應(yīng)位置查找文件的方法。用的最多的就是指定特定的命名標(biāo)準(zhǔn)。
Zend的方法
zend推薦了一種最流行的辦法,在文件名中包含路徑。例如下面的例子:
// Main.class
function __autoload($class_name) {
$path = str_replace('_', DIRECTORY_SEPARATOR, $class_name);
require_once $path.'.php';
}
$temp = new Main_Super_Class(); 所有的下劃線都會(huì)被替換成路徑中的分隔符,上例中就會(huì)去 Main/Super/Class.php文件
這種方法的缺點(diǎn)是在編碼過(guò)程中,我們必須明確的知道代碼文件應(yīng)當(dāng)所處的位置,而且由于
將文件路徑硬編碼在了類名中,如果需要修改文件夾的結(jié)構(gòu)時(shí),我們必須手工修改所有的類名。
'Include All'方法
如果是在一個(gè)開(kāi)發(fā)環(huán)境中,并且對(duì)于速度不是很在意的話,使用這個(gè)方法是非常方便的。通過(guò)將所有類文件放在一個(gè)或幾個(gè)特定文件夾中,然后通過(guò)遍歷的方式查找加載。
例如:
<?php
$arr = array (
'Project/Classes',
'Project/Classes/Children',
'Project/Interfaces'
);
foreach($arr as $dir) {
$dir_list = opendir($dir);
while ($file = readdir($dir_list)) {
$path = $dir.DIRECTORY_SEPARATOR.$file;
if(in_array($file, array('.', '..')) || is_dir($path))
continue;
if (strpos($file, ".class.php"))
require_once $path;
}
}
?>
關(guān)聯(lián)文件和位置
另外一個(gè)方法是在類文件和他的位置之間建立關(guān)聯(lián)的配置文件,例如:
// configuration.php
array_of_associations = array(
'MainSuperClass' = 'C:/Main/Super/Class.php',
'MainPoorClass' = 'C:/blablabla/gy.php'
);
調(diào)用的文件
<?php
require 'autoload_generated.php';
function __autoload($className) {
global $autoload_list;
require_once $autoload_list[$className];
}
$x = new A();
?>
當(dāng)然,如果文件特別多的時(shí)候,維護(hù)起來(lái)會(huì)是一件麻煩事,但是與在類名中硬編碼位置,哪個(gè)更好呢?
我們當(dāng)然不希望手工來(lái)維護(hù)這個(gè)列表,那么可以使用自動(dòng)生成這個(gè)文件來(lái)實(shí)現(xiàn),這個(gè)對(duì)應(yīng)關(guān)系的文件可以是php\xml\json等等。原文的作者實(shí)現(xiàn)了一個(gè)這樣的工具,仔細(xì)考慮一下的話,這個(gè)不是很難實(shí)現(xiàn),原文作者甚至發(fā)展了一個(gè)小型的 Autoload 框架,值得學(xué)習(xí)。
相關(guān)文章
php字符串函數(shù) str類常見(jiàn)用法示例
這篇文章主要介紹了php字符串函數(shù) str類常見(jiàn)用法,結(jié)合實(shí)例形式分析了php字符串函數(shù)常見(jiàn)操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2020-05-05
詳解php 使用Callable Closure強(qiáng)制指定回調(diào)類型
這篇文章主要介紹了詳解php 使用Callable Closure強(qiáng)制指定回調(diào)類型的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-10-10
PHP簡(jiǎn)單檢測(cè)網(wǎng)址是否能夠正常打開(kāi)的方法
這篇文章主要介紹了PHP簡(jiǎn)單檢測(cè)網(wǎng)址是否能夠正常打開(kāi)的方法,涉及php中curl的簡(jiǎn)單使用技巧,需要的朋友可以參考下2016-09-09
php數(shù)組函數(shù)array_key_exists()小結(jié)
本文給大家匯總介紹了php數(shù)組函數(shù)array_key_exists()的相關(guān)知識(shí)以及與in_array的性能對(duì)比,與isset的區(qū)別分析,非常的詳細(xì),有需要的小伙伴可以參考下。2015-12-12
php的PDO事務(wù)處理機(jī)制實(shí)例分析
這篇文章主要介紹了php的PDO事務(wù)處理機(jī)制,結(jié)合實(shí)例形式分析了事務(wù)的原理、功能及PDO處理事務(wù)的具體操作步驟與實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-02-02
PHP使用兩個(gè)棧實(shí)現(xiàn)隊(duì)列功能的方法
這篇文章主要介紹了PHP使用兩個(gè)棧實(shí)現(xiàn)隊(duì)列功能的方法,結(jié)合實(shí)例形式分析了php基于兩個(gè)棧實(shí)現(xiàn)隊(duì)列功能的思路與具體操作技巧,需要的朋友可以參考下2018-01-01

