下面是調用一個模型(Module)的函數。這個函數的準系統是指定一個模型(抽象化為類)的名稱,然後它會在模型目錄下面尋找這個類的指令碼執行個體化以後返回。這樣的做法有一點好處就是載入和執行個體化是自動的,你可以獲得最大的靈活性。下面請看下面的代碼,它並不長而且不複雜:
function &load_class($class_name, $param = null, $instantiate = true)
{
static $objects = array();
$class_name = ucfirst(strtolower($class_name));
if (isset($objects[$class_name])) {
return $objects[$class_name];
}
$class_file = DIR_MODELS . "/{$class_name}.inc.php";
if (file_exists($class_file)) {
require_once $class_file;
if (!class_exists($class_name)) {
return false;
} else {
$objects[$class_name] =& new $class_name($param);
return $objects[$class_name];
}
} else {
if ($instantiate) {
$objects[$class_name] = null;
}
return null;
}
}函數只有三個參數,分別是 $class_name 、$param 以及 $instaniate ,其中 $param 是建構函式的參數,$instaniate 是可選的。請注意函數中的 $objects 數組是一個靜態變數,也就是當調用完這個函數的時候數組並不會釋放,下次調用此函數時這個數組的資料是會儲存的。這樣做的好處就是可以將大部分的類執行個體了以後,如需要重複調用則直接返回這個類的執行個體就可以了,避免了重複調用,提高了效能。代碼如下:
static $objects = array();
if (isset($objects[$class_name])) {
return $objects[$class_name];
}其它繼續的代碼就是檢測是否有這個類名稱的檔案,如果有載入這個檔案並尋找指定名稱的類,如找到了這個類以後就執行個體化。這要求指令碼中類的名稱必須和指令碼的檔案名稱是一致的。我想這也有利於以後的代碼管理。
$instaniate 參數這個時候就發揮了功效,這個參數會告訴函數如果未找到則在 $objects 下面做一個標記位(null)避免函數又重複的尋找檔案名稱並重複載入和尋找。
$class_file = DIR_MODELS . "/{$class_name}.inc.php";
if (file_exists($class_file)) {
require_once $class_file;
if (!class_exists($class_name)) {
return false;
} else {
$objects[$class_name] =& new $class_name($param);
return $objects[$class_name];
}
} else {
if ($instantiate) {
$objects[$class_name] = null;
}
return null;
}其中語句:
$objects[$class_name] =& new $class_name($param);可以多次的推敲一下。$class_name 在函數中是一個字串變數。關鍵字 new 可以動態執行個體化指定字串的類(如果存在的話)。有關此調用方法可以參見 PHP 手冊和這裡。
此函數的不足之處就是如何去考慮傳遞不同個數的參數給每個不同的類的建構函式。或許可以使用 call_user_func_array 等函數實現,但是這樣的做法非常的不 Grace。在這裡需要推敲一下。其實 file_exists 等檔案存在的測試可以交給 __autoload 函數處理,不過由於其他的函數比如 interface_exists 等也會調用 __autolaod 函數,出於相容性的考慮,所以只在函數內做一個簡單的測試。
PHP5 相對 PHP4 而言更加的物件導向。我想是時候更新我們我們的編碼思想了。有關 PHP5 的類和對象,這裡有一個非常好的教程。