1. 什么是自動(dòng)加載,?自動(dòng)加載就是在實(shí)例化類的時(shí)候,,PHP自動(dòng)幫我們把需要用到的文件給require進(jìn)來,不需要我們手動(dòng)一個(gè)一個(gè)去require,; 2. 如何實(shí)現(xiàn)?1. __autoload()方法實(shí)現(xiàn)自動(dòng)加載 <?phpfunction __autoload($classname){ require $className . '.php';}$test = new Test();//在index.php同級(jí)目錄下加載Test.php文件 小項(xiàng)目這樣做當(dāng)然沒問題,,但是項(xiàng)目變大了之后就無法滿足需求了,,比如需要加載多個(gè)不同目錄的文件__autoload就無法實(shí)現(xiàn)了,因?yàn)橐粋€(gè)項(xiàng)目只能有一個(gè)__autoload,不能申明多個(gè),。那怎么解決呢,?就是下面的spl_autoload_register了。 2. spl_autoload_register方法實(shí)現(xiàn)自動(dòng)加載
需要注意的是,,當(dāng)項(xiàng)目中同時(shí)存在spl_autoload_register和__autoload時(shí),__autoload會(huì)失效,想要同時(shí)工作,,只能把__autoload作為函數(shù)注冊(cè)到spl_autoload_register中,。 function load1($className){ echo 1; if (is_file($className . '.php')) { require $className . '.php'; }}function load2($className){ echo 2; if (is_file('./app/' . $className . '.php')) { require './app/' . $className . '.php'; }}function __autoload($className){ echo 3; if (is_file('./lib/' . $className . '.php')) { require './lib/' . $className . '.php'; }}//注冊(cè)了3個(gè)spl_autoload_register('load1');spl_autoload_register('load2');spl_autoload_register('__autoload'); $config= new Config(); //Config就在本目錄下$test= new Test(); //Test在/app/Test.php//打印結(jié)果//1Hello DB//123Hello Info 當(dāng)我們想知道項(xiàng)目中注冊(cè)了多少自動(dòng)加載函數(shù)的時(shí)候,可以使用spl_autoload_functions函數(shù)
3. spl_autoload_register namespace實(shí)現(xiàn)文件規(guī)范化自動(dòng)加載 <?php//定義當(dāng)前的目錄絕對(duì)路徑define('DIR', dirname(__FILE__));//加載這個(gè)文件require DIR . './Loading.php';//采用`命名空間`的方式注冊(cè),。php 5.3 加入的//也必須是得是static靜態(tài)方法調(diào)用,,然后就像加載namespace的方式調(diào)用,注意:不能使用usespl_autoload_register('\\App\\Loading::autoload');//Loading文件使用了namespace這里也就只能使用全路徑調(diào)用// 調(diào)用三個(gè)namespace類//定位到Lib目錄下的Name.phpuse Lib\Name;Name::test();//定位到App目錄下Android目錄下的Name.phpAndroid\Name::test();//定位到App目錄下Ios目錄下的Name.php\Ios\Name::test(); Loading.php
Android/Name.php <?phpnamespace Android;class Name{ public static function test(){ echo __NAMESPACE__.' name'.PHP_EOL; }} Ios/Name.php
Lib/Name.php <?phpnamespace Lib;class Name{ public static function test(){ echo __NAMESPACE__.' name'.PHP_EOL; }} 輸出:
4. 同根命名空間下的相互調(diào)用 new Lib\Driver\Config();//報(bào)錯(cuò)C:\Users\53101\Desktop\study\php\autoload_study\Lib\Lib\Driver\Config.php is not exist 這種命名空間的調(diào)用實(shí)際上是一個(gè)相對(duì)路徑,,當(dāng)前已經(jīng)在Lib命名空間下了,,所以不需要再重復(fù)調(diào)用Lib命名空間,正確的做法是:
如果反過來在Lib/Driver/Config.php中想調(diào)用Lib/Name.php就只能使用絕對(duì)路徑引用的方式,因?yàn)橄鄬?duì)路徑已經(jīng)到了下級(jí)目錄Lib/Driver,,無法找到上級(jí)目錄Lib的文件。 //use絕對(duì)路徑use Lib\Name;Name::test();//直接絕對(duì)路徑調(diào)用\Lib\Name::test(); 總結(jié):實(shí)現(xiàn)自動(dòng)加載有兩種方式
實(shí)際使用時(shí)是配合namespace使用的,,因?yàn)镻SR-0規(guī)范可以方便地找到需要加載的文件,,命名空間在調(diào)用時(shí)實(shí)際上就已經(jīng)把路徑寫出來了,,只需要把對(duì)應(yīng)class加載進(jìn)來就可以了。 |
|