自從程式寫作方式轉換至 Class 的開發方式
就慢慢的將各功能寫成 Class , 也都將各 Class 存成獨立的檔案
例: Corder.php , class.order.php 等檔案命名方式
隨著類別產生各自的檔案,也在程式執行時,載入該頁面所需要執行的 Class
require("class.file1.php") ;
require("class.file2.php") ;
require_once("class.file3.php") ; // 為了防止重覆載入,所以多了 _once
//這樣就可以快快樂樂的使用 Class
$obj = new file1();
$obj->sayhi();
後來,慢慢的,程式越寫越大,越寫越複雜,越寫層次越多
因為,越寫越亂了....
也因此要載入的 Class 也越來越多
require("class.file1_base.php") ;
require("class.file1.php") ;
require("class.file1_ext1.php") ;
require("class.file1_ext2.php") ;
require("forder1\class.file2.php") ;
require("forder2\class.file3_base.php") ;
require("forder3\sub1\class.file3_ext1.php") ;
光寫以上7行,就感覺很難管理,更別說,更大更複雜功能,需載入來自世界各地的 Class
還好,為了防止Class沒有載入,所以我用了 class_exists 先判斷一下
if (@class_exists($wannt_class))
{
require_once($wannt_class . '.php');
}
雖然這樣子寫,有多一個判斷,但還是要載入來自世界各地的 Class 檔案
於是,就有了 __autoload()
function __autoload($class_name) {
include $path . $class_name . '.php';
}
$obj = new MyClass1();
$obj2 = new MyClass2();
//再加上 try catch
function __autoload($name) {
echo "Want to load $name.\n";
throw new Exception("Unable to load $name.");
}
try {
$obj = new NonLoadableClass(); // 宣告一個不存在的 Class
} catch (Exception $e) {
echo $e->getMessage(), "\n";
}
不過,這個會有些問題,__autoload 程式一執行,就會執行的函式那麼,如果我要自己指定載入的時間點,及變更 function 的名稱,可以嗎?
答案是,可以的,利用 spl_autoload_register
function my_autoloader($class) {
include 'classes/' . $class . '.class.php';
}
spl_autoload_register('my_autoloader');
// Or, using an anonymous function as of PHP 5.3.0
spl_autoload_register(function ($class) {
include 'classes/' . $class . '.class.php';
});
也可以在 Class 裡面新增一個 autoload 的 function
然後,在執行該 Class 時,再進行載入相關 Class
class MyClass {
public static function autoload($className) {
// ...
}
}
spl_autoload_register(array('MyClass', 'autoload'));
// Or you can use an instance :
class MyClass {
public function autoload($className) {
// ...
}
}
$instance = new MyClass();
spl_autoload_register(array($instance, 'autoload'));
稍為整理一下....
spl_autoload_register(function($class) {
if(file_exists($class.'.php'))
{
include $class.'.php';
if (!class_exists($class))
{
die('required class not present');
}
}
else
{
die('file not found');
}
});
最後,再整理出自己的版本,附加使用 include_path
define('DOC_ROOT', dirname(__FILE__)) ; //定義該專案根目錄位置
define('LIB_PATH', DOC_ROOT. '\lib') ; //定義共用LIB資料夾位置
define('CLASS_PATH', DOC_ROOT. '\class') ; //定義類別存放置置
// 增加 include_path 於設定值
$_inc_path = '';
//$_inc_path .= CLASS_PATH . PATH_SEPARATOR ; //存放類別目錄
$_inc_path .= LIB_PATH . '\activerecord\lib'. PATH_SEPARATOR ; // activerecord(ORM)函式目錄
ini_set('include_path', $_inc_path . ini_get('include_path')) ;
//ini_set('error_log', dirname(__FILE__) . '/data/error_log.txt'); //設定 error_log 記錄至檔案
//利用 匿名函式 註冊 autoload func.
spl_autoload_register(function ($class_name) {
$class_file = $class_name . '.php' ;
@include_once($class_file) ; //不能使用 require , 因為 require 如果沒有檔案,程式會中斷
if ( !class_exists($class_name) ) {
echo "no class.";
throw new Exception ("Unable to load $class_name.");
}else{
echo "class exists;";
}
// 基本上,如果在 include_path 都有設定好,是不用 file_exist
/*
if( file_exists($class_file) )
{
require_once($class_file) ;
} else {
throw new Exception("Unable to load $class_name.");
}
*/
});
try {
$obj = new myClass();
$obj->sayhi();
}catch(Exception $e){
echo $e->getMessage(), "\n";
}
沒有留言:
張貼留言