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

摘要:
php2classCI_模型{3Publicfunction__construct()4{5}67/**8*__ get魔术方法非常巧妙。值得研究的是,9*允许模型层中的类访问对象$CI 10*11*__ get12*13*Allowsmodel指向的类中的已加载类,从而使用相同的14*语法控制器访问CI的已加载的类。15*16*@paramstring17*@accessprivate18*/19publicfunction__Get20{21$CI=&get_instance();22printf;23return$CI-˃$key;24}2526publicfunctioninvokeClass()27{28//$this-˃appa调用魔术方法__get,魔术方法__get调用成员变量appa29$obj=$this-˃appa;30echo‘inner‘.__method_“”;31printf;32printf;3334$obj=$this->appb;35echo‘internal‘.__method_。“”; 36printf;37printf;38} 39} 40? 如果是这样,我们将重做…9//如果要加载的类之前已经实例化过,则直接返回10if11{12return$_classes[$class];13}1415if16{17require;18}1920//跟踪我们刚刚加载的类21//将所有加载的类保存在静态数组中_ is _ in loaded,22 is _ loaded;2324//实例化类$name,然后将实例化的类保存在静态变量$_in类中,避免下次25$_classes[$class]=new$class()时重复实例化;26返回$_类[$class];27}28}2930//---------------------------------------------------------------------3132/**33*已加载Keepstrackfwhichlibrarie。此函数由35*36*@accesspublic37*@returnarray38*/39if(!

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|

", $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

", __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__ . "

";
31         printf("obj is: |%s|

", var_export($obj, true));
32         printf("obj->getApp: %s

", $obj->getApp());
33 
34         $obj = $this->appb;
35         echo 'inner ' . __METHOD__ . "

";
36         printf("obj is: |%s|

", var_export($obj, true));
37         printf("obj->getApp: %s

", $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__ . "

";
 9 $controller->get();
10 ?>

运行php index.php输出结果如下:

E:myphp esearchCodeIgniter_2.2.0ci_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 esearchCodeIgniter_2.2.0ci_studyindex.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框架此处调用实在是巧炒,非常值得学习借鉴。

免责声明:文章转载自《CI框架中一个类中调用另一个类中已经加载对象测试》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【内核】——中断和异常Zeal——好用的离线 API 文档大全!下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

CI-持续集成(1)-软件工业“流水线”概述

CI-持续集成(1)-软件工业“流水线”概述 1   概述 持续集成(Continuous integration)是一种软件开发实践,即团队开发成员经常集成它们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误 [1]。 持续集成 相当于将传统工...

SpringCloud-OAuth2(四):改造篇

本片主要讲SpringCloud Oauth2篇的实战改造,如动态权限、集成JWT、更改默认url、数据库加载client信息等改造。 同时,这应该也是我这系列博客的完结篇。 关于Oauth2,我也想说几句: 如果真的要应用到企业级项目当中去,必须要进行充足的准备,因为默认的配置、UI等很多都不是通用的(不适用于各个公司), 但是这套框架还好留了很多适配...

SqlServer nvarchar中的中文字符匹配,更改SqlServer实例和数据库排序规则的办法

我们都知道在SqlServer中的nvarchar类型可以完美的存储诸如中文这种unicode字符,但是我们会发现有时候查询语句去查询nvarchar列的时候查不出来。 为什么nvarchar类型有时候需要前面带N的字符串才能查出结果 比如假如现在有一张表T_UserInfo如下,其中列[Name]为nvarchar类型用于存储中文姓名: CREATE T...

一种用buildkit打造免registry的local cd/ci工具,打通vscodeonline与openfaas模拟cloudbase打造碎片化编程开发部署环境的设想

本文关键字:如何直接修改docker中的文件,从外部编辑dockernamespace内文件,share data between host and container?,定制镜像和容器,不经过任何registry重建/修改/commit docker镜像,Creating an image from a commited snapshot,把openfa...

OA之手机短信模块(一)

  前言    最近太忙,没有时间写博客,也发觉没有主题可写.就把目前做的模块拿出来赚点点击率.也适当回击一下以前公司同事写着一块,却不肯说原理给我们听.其实这个很简的.. 用途 1.       可以用于OA,即时通讯,预警系统等. 2.       也可以写成组件,供其它模块调用,如工作流等. 开发手机技术简介 1.       SP服务提供商.现在移...

[转]Maven多模块结构下版本管理的正确姿势-revision

转自: Maven多模块结构下版本管理的正确姿势(CI Friendly Versions) - ${revision} 在使用Maven多模块结构工程时,配置版本是一个比较头疼的事。继承版本,依赖版本,自身版本,都需要单独定义,很是麻烦。但其实Maven已经提供了这种CI版本的管理方式,下面来介绍具体用法。 从Maven 3.5.0-beta-1版本开始...