天天看點

談談php中自動裝載函數__autoload

談談php中自動裝載函數__autoload

在使用phpexcel類庫的時候,發現一個有意思的事情:

談談php中自動裝載函數__autoload

看上面的檔案結構,隻有一個phpexcel.php和一個目錄,而我們在使用這個類庫的時候,隻需要将phpexcel.php檔案包含進去就好了。其他的檔案裝載就不需要理會啦。

例如上面的文章提到的使用方式:require_once('./phpexcel1.7.3/PHPExcel.php');後面使用其他的類庫都沒有包含。

看了PHPExcel.php的代碼後,發現其中的原因:

它首先使用下面這樣的一個自動裝載代碼

/** PHPExcel root directory */

if (!defined('PHPEXCEL_ROOT')) {

 define('PHPEXCEL_ROOT', dirname(__FILE__) . '/');

 require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');

 PHPExcel_Autoloader::Register();

 PHPExcel_Shared_ZipStreamWrapper::register();

 // check mbstring.func_overload

 if (ini_get('mbstring.func_overload') & 2) {

 throw new Exception('Multibyte function overloading in PHP must be disabled for string functions (2).');

 }

}

if (!defined('PHPEXCEL_ROOT')) 

{

   define('PHPEXCEL_ROOT', dirname(__FILE__) . '/');

   require(PHPEXCEL_ROOT .'PHPExcel/Autoloader.php');

   PHPExcel_Autoloader::Register();

 ............

下面是自動裝載的實作代碼:隻要功能是将Load函數自動裝載為spl_autoload();

class PHPExcel_Autoloader

public static function Register() {

return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'));

} // function Register()

public static function Load($pObjectName){

if ((class_exists($pObjectName)) || (strpos($pObjectName, 'PHPExcel') === False)) {

return false;

}

$pObjectFilePath = PHPEXCEL_ROOT.

str_replace('_',DIRECTORY_SEPARATOR,$pObjectName).

'.php';

if ((file_exists($pObjectFilePath) === false) || (is_readable($pObjectFilePath) === false)) {

require($pObjectFilePath);

} // function Load()

當php執行代碼的時候發現沒有引用相關的檔案就會執行Load的靜态函數,這樣在Load裡面實作函數的裝載顯得簡單,友善。

舉個例子:我們在使用PHPExcel讀寫類的時候,代碼如下:

reader_obj = new PHPExcel_Reader_Excel2007();

excel2007在檔案中的目錄結構如下:

談談php中自動裝載函數__autoload

這樣他就調用了

 PHPEXCEL_ROOT. str_replace('_',DIRECTORY_SEPARATOR,$pObjectName). '.php';

 将其變為檔案的目錄結構,并将檔案包含。

我們在編寫php程式時,通常将一些功能包裝成類的方式,由于在實作某一寫功能的時候,可能要加載大量的相關類庫,通過使用這樣一種自動裝載函數,

大大減少加載庫檔案的混亂。

當然我們也可以自己定義一套操作庫檔案的函數:這裡提供一個簡單的例子:

//約定$class的格式使用點來标記檔案夾目錄

//例如:檔案/modules/example.class.php   import("modules.example")

function import($class)

    $path = ROOT . strtr($class, '.', '/') . ".class.php";

  if(is_file($path))

  {

    include_once($path);

  }

  else