CI框架中一個類中調用另外一個類中已經加載對象測試

controller.phpphp

 1 <?php
 2 class CI_Controller {
 3 
 4     private static $instance;
 5 
 6     public function __construct()
 7     {
 8         self::$instance =& $this;
 9 
10         foreach (is_loaded() as $var => $class)
11         {
12             $this->$var =& load_class($class);
13             $obj = $this->$var;
14             printf("var: |%s|, class: |%s|, obj: |%s|\n\n", $var, $class, var_export($obj, true));
15         }
16     }
17 
18     public static function &get_instance()
19     {
20         return self::$instance;
21     }
22 
23     public function get()
24     {
25         require 'model.php';
26         $model = new CI_Model();
27         $str = $model -> invoteClass();
28         return $str;
29     }
30 }
31 ?>

 model.php設計模式

 1 <?php
 2 class CI_Model {
 3     public function __construct()
 4     {
 5     }
 6 
 7     /**
 8      * 這個地方的__get魔術方法使用很是巧妙,值得研究一下
 9      * 容許model層的類去訪問對象$CI所指向的類中已經加載的類
10      *
11      * __get
12      *
13      * Allows models to access CI's loaded classes using the same
14      * syntax as controllers.
15      *
16      * @param   string
17      * @access private
18      */
19     public function __get($key)
20     {
21         $CI = &get_instance();
22         printf("inner %s\n\n", __METHOD__);
23         return $CI->$key;
24     }
25 
26     public function invoteClass()
27     {
28         //$this->appa調用魔術方法__get,魔術方法__get調用類CI_Controller中的成員變量appa
29         $obj = $this->appa;
30         echo 'inner ' . __METHOD__ . "\n\n";
31         printf("obj is: |%s|\n\n", var_export($obj, true));
32         printf("obj->getApp: %s\n\n", $obj->getApp());
33 
34         $obj = $this->appb;
35         echo 'inner ' . __METHOD__ . "\n\n";
36         printf("obj is: |%s|\n\n", var_export($obj, true));
37         printf("obj->getApp: %s\n\n", $obj->getApp());
38     }
39 }
40 ?>

common.php數組

 1 <?php
 2 if ( ! function_exists('load_class'))
 3 {
 4     function &load_class($class)
 5     {
 6         static $_classes = array();
 7 
 8         // Does the class exist?  If so, we're done...
 9         // 若是要加載的類之前已經實例化過,則直接返回它
10         if (isset($_classes[$class]))
11         {
12             return $_classes[$class];
13         }
14 
15         if (file_exists($class.'.php'))
16         {
17             require($class.'.php');
18         }
19 
20         // Keep track of what we just loaded
21         //將全部加載過的類保存在靜態數組_is_loaded中,
22         is_loaded($class);
23 
24         //實例化類$name(好比CI_Input),而後將實例化後的類保存在靜態變量$_classes中,避免下次重複實例化
25         $_classes[$class] = new $class();
26         return $_classes[$class];
27     }
28 }
29 
30 // --------------------------------------------------------------------
31 
32 /**
33 * Keeps track of which libraries have been loaded.  This function is
34 * called by the load_class() function above
35 *
36 * @access   public
37 * @return   array
38 */
39 if ( ! function_exists('is_loaded'))
40 {
41     function &is_loaded($class = '')
42     {
43         static $_is_loaded = array();
44 
45         if ($class != '')
46         {
47             $_is_loaded[strtolower($class)] = $class;
48         }
49 
50         return $_is_loaded;
51     }
52 }
53 
54 function &get_instance()
55 {
56     return CI_Controller::get_instance();
57 }
58 ?>

appa.phpapp

 1 <?php
 2 class appA {
 3     public function __construct() {
 4     }
 5 
 6     public function getApp() {
 7         return 'this is appa';
 8     }
 9 }
10 
11 ?>

appb.php框架

 1 <?php
 2 class appB {
 3     public function __construct() {
 4     }
 5 
 6     public function getApp() {
 7         return 'this is appb';
 8     }
 9 }
10 ?>

index.php學習

 1 <?php
 2 require 'controller.php';
 3 require 'common.php';
 4 
 5 load_class('appA');
 6 load_class('appB');
 7 $controller = new CI_Controller();
 8 echo 'inner ' . __FILE__ . "\n\n";
 9 $controller->get();
10 ?>

運行php index.php輸出結果以下:ui

E:\myphp\research\CodeIgniter_2.2.0\ci_study>php index.php
var: |appa|, class: |appA|, obj: |appA::__set_state(array(
))|this

var: |appb|, class: |appB|, obj: |appB::__set_state(array(
))|spa

inner E:\myphp\research\CodeIgniter_2.2.0\ci_study\index.php設計

inner CI_Model::__get

inner CI_Model::invoteClass

obj is: |appA::__set_state(array(
))|

obj->getApp: this is appa

inner CI_Model::__get

inner CI_Model::invoteClass

obj is: |appB::__set_state(array(
))|

obj->getApp: this is appb

 

類CI_Model中並無加載類appA與appB,確能夠調用這兩個類中的方法並取得數據,這裏巧炒的採用了魔術方法__get的功能,並採用了單實例的設計模式實例了上述的調用過程,CI框架此處調用實在是巧炒,很是值得學習借鑑。

相關文章
相關標籤/搜索