您的位置:首页 > 其它

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

2016-03-08 15:36 429 查看
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框架此处调用实在是巧炒,非常值得学习借鉴。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: