php類檔案自動載入(autoload)
php實現類檔案自動載入有兩種辦法:
- 魔術方法:__autoload();
- SPL標準庫提供的spl_autoload_register();
一、__autoload()
__autoload()是php中的一個魔術方法,在程式碼中當呼叫不存在的類時會自動呼叫該方法。
假如現在有以下兩個類檔案:
//Test1.php檔案
<?php
class Test1{
static function test(){
echo "test1";
}
}
//Test2.php檔案
<?php
class Test2{
static function test(){
echo "test2";
}
}
現在Test.php檔案中要用到 Test1.php 和 Test2.php 中的類:
//Test.php檔案
<?php
include "Test1.php";
include "Test2.php";
Test1::test();
Test2::test();
用 include 或require 的問題是當我要呼叫的類很多的時候,include 或 require也會很多,造成程式碼的冗雜,而且每次執行到 Test.php 檔案的時候都要載入這麼多檔案,有些檔案還不一定用到,那就浪費了很多記憶體,降低效率。再者是當你某個類檔案被刪掉了,你還得去修改 Test.php 檔案。
由於這些原因,我們用 __autoload() 去代替 include
//Test.php檔案
<?php
function __autoload($class){
if(file_exists($class.".php")){
require_once($class.".php");
}else{
die("檔案不存在!");
}
}
Test1::test();
Test2::test();
__autoload() 魔術方法的作用是當你呼叫不存在的類時會被自動呼叫,在 Test.php檔案中我們呼叫 類Test1 和 類Test2,由於我們沒有顯式的引用類檔案,那麼系統就會自動呼叫 __autoload() 方法。
但是,到現在為止 __autoload() 方法基本上被廢棄了!為啥呢?因為:
1、最大的缺陷就是一個檔案中不允許有多個 __autoload()方法,想象一下,你的專案引用了別人的一個專案,你的專案中有一個 __autoload,別人的專案也有一個__autoload,這樣兩個__autoload就衝突了。解決的辦法就是修改__autoload成為一個,這無疑是非常繁瑣的。
2、假如你的專案中的類根據不同的用處放在不同的資料夾中 classes 和 core,然後Test.php檔案中要分別呼叫裡面對應的類,怎麼搞?這樣?
function __autoload($class){
if(file_exists("classes/".$class.".php")){
require_once("classes/".$class.".php");
}else{
die("檔案不存在!");
}
}
function __autoload($class){
if(file_exists("core/".$class.".php")){
require_once("core/".$class.".php");
}else{
die("檔案不存在!");
}
}
Test1::test();
Test2::test();
這樣做的話會出現致命錯誤,因為 __autoload()重複定義!(其實第1點的原因也是一樣)
為了解決這個問題,於是就有 spl_autoload_register()
二、spl_autoload_register()
好,到了這一步,我們先不說 spl_autoload_register(),既然不用__autoload(),那麼我們就自己定義負責類載入的函式:
function my_autoload1($class){
if(file_exists("classes/".$class.".php")){
require_once("classes/".$class.".php");
}else{
die("檔案不存在!");
}
}
function my_autoload2($class){
if(file_exists("core/".$class.".php")){
require_once("core/".$class.".php");
}else{
die("檔案不存在!");
}
}
//現在我們就可以載入類檔案啦
my_autoload1("Test1");
my_autoload2("Test2");
Test1::test();
Test2::test();
但是如上程式碼所示,直接呼叫我們的自定義類檔案載入函式跟 include 有啥區別嗎?這時 spl_autoload_register 就派上用場了。
顯然,創造一個負責類檔案載入函式不是為了讓我們直接呼叫它,而是讓PHP在需要類定義的時候為我們呼叫它。我們稱這種功能為“自動載入”。
要開啟“自動載入”功能,需要將載入函式註冊到PHP中:
spl_autoload_register("my_autoload1");
我們重新實現 Test.php:
//Test.php檔案
function my_autoload1($class){
if(file_exists("classes/".$class.".php")){
require_once("classes/".$class.".php");
}else{
die("檔案不存在!");
}
}
function my_autoload2($class){
if(file_exists("core/".$class.".php")){
require_once("core/".$class.".php");
}else{
die("檔案不存在!");
}
}
//將載入函式註冊到PHP中
spl_autoload_register("my_autoload1");
spl_autoload_register("my_autoload2");
Test1::test();
Test2::test();
這樣就是實現了PHP的類檔案自動載入功能。