CI框架中一个类中调用另一个类中已经加载对象测试
controller.php
<?php
class CI_Controller { private static $instance; public function __construct()
{
self::$instance =& $this; foreach (is_loaded() as $var => $class)
{
$this->$var =& load_class($class);
$obj = $this->$var;
printf("var: |%s|, class: |%s|, obj: |%s|\n\n", $var, $class, var_export($obj, true));
}
} public static function &get_instance()
{
return self::$instance;
} public function get()
{
require 'model.php';
$model = new CI_Model();
$str = $model -> invoteClass();
return $str;
}
}
?>
model.php
<?php
class CI_Model {
public function __construct()
{
} /**
* 这个地方的__get魔术方法使用非常巧妙,值得研究一下
* 允许model层的类去访问对象$CI所指向的类中已经加载的类
*
* __get
*
* Allows models to access CI's loaded classes using the same
* syntax as controllers.
*
* @param string
* @access private
*/
public function __get($key)
{
$CI = &get_instance();
printf("inner %s\n\n", __METHOD__);
return $CI->$key;
} public function invoteClass()
{
//$this->appa调用魔术方法__get,魔术方法__get调用类CI_Controller中的成员变量appa
$obj = $this->appa;
echo 'inner ' . __METHOD__ . "\n\n";
printf("obj is: |%s|\n\n", var_export($obj, true));
printf("obj->getApp: %s\n\n", $obj->getApp()); $obj = $this->appb;
echo 'inner ' . __METHOD__ . "\n\n";
printf("obj is: |%s|\n\n", var_export($obj, true));
printf("obj->getApp: %s\n\n", $obj->getApp());
}
}
?>
common.php
<?php
if ( ! function_exists('load_class'))
{
function &load_class($class)
{
static $_classes = array(); // Does the class exist? If so, we're done...
// 如果要加载的类以前已经实例化过,则直接返回它
if (isset($_classes[$class]))
{
return $_classes[$class];
} if (file_exists($class.'.php'))
{
require($class.'.php');
} // Keep track of what we just loaded
//将所有加载过的类保存在静态数组_is_loaded中,
is_loaded($class); //实例化类$name(比如CI_Input),然后将实例化后的类保存在静态变量$_classes中,避免下次重复实例化
$_classes[$class] = new $class();
return $_classes[$class];
}
} // -------------------------------------------------------------------- /**
* Keeps track of which libraries have been loaded. This function is
* called by the load_class() function above
*
* @access public
* @return array
*/
if ( ! function_exists('is_loaded'))
{
function &is_loaded($class = '')
{
static $_is_loaded = array(); if ($class != '')
{
$_is_loaded[strtolower($class)] = $class;
} return $_is_loaded;
}
} function &get_instance()
{
return CI_Controller::get_instance();
}
?>
appa.php
<?php
class appA {
public function __construct() {
} public function getApp() {
return 'this is appa';
}
} ?>
appb.php
<?php
class appB {
public function __construct() {
} public function getApp() {
return 'this is appb';
}
}
?>
index.php
<?php
require 'controller.php';
require 'common.php'; load_class('appA');
load_class('appB');
$controller = new CI_Controller();
echo 'inner ' . __FILE__ . "\n\n";
$controller->get();
?>
运行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框架此处调用实在是巧炒,非常值得学习借鉴。
CI框架中一个类中调用另一个类中已经加载对象测试的更多相关文章
- 在java的多态调用中,new的是哪一个类就是调用的哪个类的方法。
在java的多态调用中,new的是哪一个类就是调用的哪个类的方法.(x) 原因: ava多态有两种情况:重载和覆写 在覆写中,运用的是动态单分配,是根据new的类型确定对象,从而确定调用的方法: 在重 ...
- 关于ligerui 中 grid 表格的扩展搜索功能在远程数据加载时无法使用的解决办法
要想使用grid里的扩展搜索功能,除了要引用ligerui主要的js文件外,还必须引入下面的JS文件: 1.Source\demos\filter\ligerGrid.showFilter.js 2. ...
- win7/8系统中php5.3和5.4、5.5不能加载php_curl.dll解决办法
win7/8系统中php5.3和5.4.5.5不能加载php_curl.dll解决办法 作者:用户 来源:互联网 时间:2016-06-23 18:54:33 php变量注释系统模块 摘要: 本文 ...
- 在NVIDIA A100 GPU中使用DALI和新的硬件JPEG解码器快速加载数据
在NVIDIA A100 GPU中使用DALI和新的硬件JPEG解码器快速加载数据 如今,最流行的拍照设备智能手机可以捕获高达4K UHD的图像(3840×2160图像),原始数据超过25 MB.即使 ...
- 使用MUI框架,模拟手机端的下拉刷新,上拉加载操作。
套用mui官方文档的一句话:“开发者只需关心业务逻辑,实现加载更多数据即可”.真的是不错的框架. 想更多的了解这个框架:http://dev.dcloud.net.cn/mui/ 那么如何实现下拉刷新 ...
- 做一个可复用的 echarts-vue 组件(延迟动画加载)
在 vue 项目使用 echarts 的场景中,以下三点不容忽视:1. 可视化的数据往往是异步加载的:2. 若一个页面存在大量的图表( 尤其当存在关系图和地图时 ),往往会导致该页面的渲染速度很慢并可 ...
- Python+selenium 自动化-启用带插件的chrome浏览器,调用浏览器带插件,浏览器加载配置信息。
Python+selenium 自动化-启用带插件的chrome浏览器,调用浏览器带插件,浏览器加载配置信息. 本文链接:https://blog.csdn.net/qq_38161040/art ...
- java同一个类中,构造器如何调用另一个重载的构造器?
构造器里面调用其它构造器,格式方法如下:1.使用this调用另一个重载构造器,只能在构造器中使用:2.必须写在构造器执行体的第一行语句: 示例如下: import static java.lang.S ...
- 解决Eclipse中“诡异”的错误:找不到或无法加载主类
记录下来遇到的(问题,解决方法),是更有效的解决问题的方式.(原谅我领悟的太晚与懒,从此用更有意义的方法,做一个更有意义的人) 因为遇到了多次,参考同一个方法,原文连接:https://blog.cs ...
随机推荐
- Java生成验证码并进行验证(转)
本文转自http://blog.csdn.net/worm0527/article/details/51030864 一.实现思路 使用BufferedImage用于在内存中存储生成的验证码图片 使用 ...
- PDO防止SQL注入具体介绍
<span style="font-size:18px;"><?php $dbh = new PDO("mysql:host=localhost; db ...
- Office EXCEL 如何为宏命令指定快捷键或者重新设置快捷键
1 工具-宏-宏,打开宏窗口 2 鼠标单击任意宏将其选中,点击宏选项,即可修改或为他增加快捷键. 3 注意,你直接在Visual Basci编辑器里面改是不行的,因为加了'的只是注释而已
- 深入浅出Redis(三)高级特性:管道
Redis是一个响应式的服务,当client发送一个请求后,就处于堵塞状态等待Redis返回结果. 这样一次命令消耗的时间就包含三个部分:请求从client到server的时间.结果从server到c ...
- CSS 相对|绝对(relative/absolute)定位系列(一)
一.有话要说 以前写内容基本上都是:眼睛一亮——哟呵,这个不错,写!然后去古人所说的茅房里蹲会儿,就有写作的思路了.但是,构思相对/绝对(relative/absolute)定位系列却有好些时日,考虑 ...
- leetcode:283. Move Zeroes(Java)解答
转载请注明出处:z_zhaojun的博客 原文地址:http://blog.csdn.net/u012975705/article/details/50493772 题目地址:https://leet ...
- mysql学习笔记之mysql数据库的安装
1.执行mysql安装包选择自己定义安装(安装路径不要带中文,否则安装会出错! ) 2.一个mysql想要操作成功须要有三部分:server端,数据段,数据. 3.server软件文件夹: 4.数据文 ...
- Android网络编程(三)Volley使用方法全解析
相关文章 Android网络编程(一)HTTP协议原理 Android网络编程(二)HttpClient与HttpURLConnection 前言 Volley想必许多人都用过,为了建立网络编程的知识 ...
- Python开发【第2节】【Python运算符】
Python语言支持以下类型的运算符: 算术运算符 比较(关系)运算符 赋值运算符 逻辑运算符 位运算符 成员运算符 身份运算符 运算符优先级 1.算术运算符 假设变量a = 10,变量b = 21: ...
- Servlet的引入
一.分析 此模式有问题: 1.jsp需要呼叫javabean StudentService stuService = new StudentServiceImpl(); List<Student ...