2013年1月22日 19:35:25
大概過程:所有URL請求->重定向到index.php->加載一個類A->分析URL得到參數信息和將要調用的另一個類B->加載這個類B,並將參數信息傳遞給該類->執行->結束.
入口文件(通過.htaccess文件中的rewrite功能把所有請求都轉向這個文件):
test.php <?php include './a.php'; //存放處理URL獲得參數信息的祖先類A $objA = new A(); $objA->run(); exit;
主要入口處理類(相當於zend framework的front,用於處理和分發請求):
a.php <?php class A { public function __construct() { var_dump('A 構造函數'); } public function run() { include './b.php'; $obj = new B(); $obj->action(); } public function __destruct() { var_dump('A 析構函數'); } }
功能類,處理分發來的請求(超級類將URL分解獲得信息,動態new此class,並將信息交給此class處理)
b.php <?php class B { public function action() { var_dump('B action函數'); } }
如果類B沒有繼承類A,執行test.php入口文件的代碼結果很容易知道:
string 'A 構造函數' (length=14) string 'B action函數' (length=14) string 'A 析構函數' (length=14)
如果類B繼承了主要入口請求處理類A:
b.php (繼承了A) <?php class B extends A { public function action() { var_dump('B action函數'); } }
那么結果是這樣的:
string 'A 構造函數' (length=14) string 'A 構造函數' (length=14) string 'B action函數' (length=14) string 'A 析構函數' (length=14) string 'A 析構函數' (length=14)
結論1:如果B繼承了A,當在A中創建B的對象那么會再次調用A的構造函數,也只調用A的構造函數
結論2:如果要想在B中使用A中的數據(往往是對入口URL處理得到的結果),就必須在A的構造函數中定義這些值
如果在類B中寫了B的構造函數會怎樣?:
<?php class B extends A { public function B() { var_dump('B 構造函數'); } public function action() { var_dump('B action函數'); } }
那么結果是這樣的:
string 'A 構造函數' (length=14) string 'B 構造函數' (length=14) string 'B action函數' (length=14) string 'A 析構函數' (length=14) string 'A 析構函數' (length=14)
對,和你想的一樣,A的構造函數沒有執行,因為子類的構造函數覆蓋了父類的構造函數
知道這個結果沒有什么可喜可賀的,重要的是:
結論3:不能寫子類的構造函數,否則你別想從父類哪里得到任何動態信息
結論4:最好將類名和類成員函數名字區分開,避免將類名和方法名寫的一樣(別笑,這樣說不是廢話,看下邊代碼),像zf做的那樣,類名后邊加上'Controller'后綴,方法名后邊加上'Action'后綴
我想大部分人都這樣干過 <?php class index { public function index() { } }
如果這樣套到單一入口框架中就不行了.
別急,還有:
結論5:因為每次執行子類B都會執行兩次A的構造函數,因此最好將類A設計成單例模式
ok,木有了.