CI框架中一个类中调用另一个类中已经加载对象测试

controller.php

 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.php

 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输出结果如下:

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

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

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框架此处调用实用是巧炒,非常值得学习借鉴。

时间: 2024-08-06 07:54:38

CI框架中一个类中调用另一个类中已经加载对象测试的相关文章

关于android中gridview数据量很大的时候,在加载gridview时会出现卡顿的现象

好的解决办法就是先加载一定数量的数据,然后在最下方提示正在加载! 动态加载就是把放入adapter中的数据分好几次加载.在用户拖动gridview时再加载一定的数据,和sina微博的客户端类似. 给gridview添加OnScrollListener监听事件默认会覆盖下面两个方法: 下面列举个列子: <com.ui.widget.LazyGridView xmlns:android="http://schemas.android.com/apk/res/android" andr

如何在App中实现朋友圈功能之七快速实现上拉加载朋友圈功能——箭扣科技Arrownock

如何在App中实现朋友圈功能 之七 快速实现上拉加载朋友圈功能 逻辑分析: 取出缓存postList里的最后一条数据postList a. 如果lastPost存在,说明缓存里有数据,接着取出数据库中与lastPost时间最接近的一条latestPost,以它们的created_at作为关键查询条件,去服务器取limit条(比如10)数据: 1. 如果服务器返回的Post数量大于0,将Post存入数据库,之后需要做两个查询动作: 查询出新的Like和Comment:根据本地数据库里的最新一条Li

主流图片加载框架ImageLoader、Glide、Picasso、Fresco性能分析---图片加载速度比较

图片加载这种实现繁琐,可复用性又极强的东西,自然是选择使用图片加载框架来快速实现. 像是Android-Universal-Image-Loader.Glide.Picasso.Fresco之类, 但是这时候的烦恼在于,这么多图片加载框架到底谁最实用? 有说Fresco,因为支持WebP,还是用了NDK来加载图片,减少JavaHeap的使用 有Picasso,简洁高效 有说Glide,Picasso升级,可以加载Gif,在Picasso基础上扩展了很多方法 ImageLoader 使用最广,因为

使用MUI框架,模拟手机端的下拉刷新,上拉加载操作。

套用mui官方文档的一句话:"开发者只需关心业务逻辑,实现加载更多数据即可".真的是不错的框架. 想更多的了解这个框架:http://dev.dcloud.net.cn/mui/ 那么如何实现上拉刷新,下拉加载的功呢? 首先需要一个容器: 1 <!--下拉刷新容器--> 2 <div id="refreshContainer" class="mui-content mui-scroll-wrapper"> 3 <di

android开发中一个activity如何调用另一个xml中的控件

有时候,我们需要在一个Activity中调用另一个xml布局文件,即非本Activity所绑定的xml布局文件中的控件,这时候就不能直接findViewById,不然会报错指向空对象,这时就需要像下面这样做. LayoutInflater factory = LayoutInflater.from(当前类.this); View layout = factory.inflate(R.layout.你要获取的另一个XML, null); TextView textview = (TextView)

使用自定义的item、Adapter和AsyncTask、第三方开源框架PullToRefresh联合使用实现自定义的下拉列表(从网络加载图片显示在item中的ImageView)

AsyncTask使用方法详情:http://www.cnblogs.com/zzw1994/p/4959949.html 下拉开源框架PullToRefresh使用方法和下载详情:http://www.cnblogs.com/zzw1994/p/4992194.html 具体实现的代码如下: item.xml: 1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:and

Android 一个应用程序调用另一个应用程序

实现行业应用调用我们可以Get到哪些技能? * Activity的singleTask的启动模式 * 界面跳转的基本实现 * 前台Service的基本介绍和实现 * SharedPreference的简单用法 实现行业应用调用的目的 在XHL应用程序中去调用MPos应用程序,借助MPos的一些界面完成特殊的功能. 实现行业应用调用步骤 (1)创建名为XHL的应用程序 (2)创建名为MPos的应用程序 代码讲解 1.创建名为XHL的应用程序的界面 如下是XHL的主界面 public class M

5.cocos2dx中关于draw绘图,声音和音效,预加载,播放与停止Vs暂停和恢复,音量控制

 1 draw绘图 头文件 T19Draw.h #ifndef __T19Draw_H__ #define __T19Draw_H__ #include "cocos2d.h" #include "TBack.h" USING_NS_CC; class T19Draw:public TBack { public: static CCScene * scene(); CREATE_FUNC(T19Draw); bool init(); void draw(); }

UI中多线程的创建以及定时器与图片的异步加载

- (void)viewDidLoad { [super viewDidLoad]; _imgView = [[UIImageView alloc]initWithFrame:self.view.bounds]; _imgView.contentMode =  UIViewContentModeScaleAspectFit; [self.view addSubview:_imgView]; // Do any additional setup after loading the view, ty