用户
 找回密码
 入住 CI 中国社区
搜索
查看: 10691|回复: 12
收起左侧

[讨论/交流] 关于 $CI = &get_instance() 求指教

[复制链接]
发表于 2013-5-20 21:04:55 | 显示全部楼层 |阅读模式
CI官方手册里面说:

$CI =& get_instance();
这十分重要. 通过引用的方式赋给变量将使用原始的 CodeIgniter 对象,而不是创建一个副本。

但是php的官方手册说 $this 是一个到调用对象的引用;

那么既然 $this  是一个引用; 那 CI 里面为什么还要用到  &$this 呢?  这个&好像是多余的呀;搞不懂了;求高手指教啊{:soso_e105:}
发表于 2015-6-5 14:57:12 | 显示全部楼层
ciuseronez 发表于 2013-5-21 11:25
**** 作者被禁止或删除 内容自动屏蔽 ****

在 PHP 中引用意味着用不同的名字访问同一个变量内容。这并不像 C 的指针,替代的是,引用是符号表别名。注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字。最接近的比喻是 Unix 的文件名和文件本身——变量名是目录条目,而变量内容则是文件本身。引用可以被看作是 Unix 文件系统中的 hardlink。链接:http://php.net/manual/zh/language.references.whatare.php意思就是说加上&后,就是一个别名
self::instance = &$this
是指self::instance是$this的一个别名,如果这里直接使用self::instance = $this的话,self::instance其实是对$this的一个复制
$this是一个引用的意思其实是对这个实例的一个别名


然后再看这个,http://php.net/manual/zh/language.references.return.php
CI_Controller::get_instance 在定义时前面加&是表示这个方法应该返回一个引用,
而在调用的时候也需要加一个&符号,表示是对引用的绑定,而不是通常的赋值 ,可以在上面这个链接看到说明


&get_instance()其实可以等价于&CI_Controller::get_instance()
以上也是个人理解,是在楼主提出这个问题以后去查的资料
发表于 2013-5-21 13:46:09 | 显示全部楼层
你说的都不错,但是你没有注意 get_instance 的使用场景,这个方法并不是用在控制器中的。
而是用在控制器外面,比如类库中,想操作 CI 超级对象的时候,超级对象实际上就是当前控制器的实例。

所以这里使用引用传递是没有问题的。
发表于 2015-9-10 16:36:57 | 显示全部楼层
Hex 发表于 2013-5-21 13:46
你说的都不错,但是你没有注意 get_instance 的使用场景,这个方法并不是用在控制器中的。
而是用在控制器 ...

确实应该是应该 return &CI_Controller::get_instance(); 这么写吧?

我写了下面的例子
PHP复制代码
<?php
error_reporting(E_ALL);
class A
{
        public $i = 0;
        static $instance;
        public static function &getInstance()
        {
                if (is_null(self::$instance)) {
                        self::$instance = new A();
                }
                return self::$instance;
        }
}
 
$aa = A::getInstance();
A::$instance = null;
var_dump($aa->i);       //正常,说明$aa是A的副本
 
$bb = &A::getInstance();
A::$instance = null;
var_dump($bb->i);       //报错 Notice: Trying to get property of non-object, 证明$bb是引用
 
 
复制代码



可见如果不加&的话,虽然在调用$CI = &get_instance();的时候是引用,但是在get_instance这个方法里面却返回的是CI实例的副本了,这应该和CI的本意是相违背的吧?
发表于 2013-5-21 10:21:50 | 显示全部楼层
这里哪有 $this ?
 楼主| 发表于 2013-5-21 11:25:26 | 显示全部楼层
Hex 发表于 2013-5-21 10:21
这里哪有 $this ?

亲爱的Hex,是这样的:CI官方手册说调用get_instance()函数时,要用&引用符号;原因是为了防止对象生成副本;说必须这样子用: $CI =& get_instance();
这个函数在CodeIgniter.php里面;但这个函数的实体是这样的:
function &get_instance()
{
        return CI_Controller::get_instance();
}
而CI_Controller::get_instance()是这样子的:
public static function &get_instance()
{
        return self:instance;
}
而self:instance是这样子的: self:instance =& $this;

亲爱的Hex,你看,get_instance() 这个函数用了N次&,而最终只是为了得到 $this;
php官方手册已经说了 $this 伪变量是一个到对象的引用;  那为什么 CI 还要如此大费周章的使用&呢?
直接传递 $this  好像也并不是复制整个对象呀     求您指导下
发表于 2013-9-16 15:42:52 | 显示全部楼层
学到了,学到了
发表于 2015-6-4 14:29:28 | 显示全部楼层
Hex 发表于 2013-5-21 13:46
你说的都不错,但是你没有注意 get_instance 的使用场景,这个方法并不是用在控制器中的。
而是用在控制器 ...

牛叉的很那
发表于 2015-6-6 12:36:08 | 显示全部楼层
本帖最后由 570999242 于 2015-6-6 12:48 编辑
ahcheqiu 发表于 2015-6-5 14:57
在 PHP 中引用意味着用不同的名字访问同一个变量内容。这并不像 C 的指针,替代的是,引用是符号表别名。 ...

对于"CI官方手册说调用get_instance()函数时,要用&引用符号;原因是为了防止对象生成副本"这一句里面的"防止对象生成副本",类比Unix中的硬链接、软链接,是不是就是防止生成软链接,就像windows中的,只生成某个软件的启动exe的别名,而不要发送或复制快捷方式到其他地方而产生快捷方式的复制?
发表于 2015-6-8 10:47:47 | 显示全部楼层
570999242 发表于 2015-6-6 12:36
对于"CI官方手册说调用get_instance()函数时,要用&引用符号;原因是为了防止对象生成副本"这一句里面的" ...

生成副本的意思是应该就是指复制了一份文档上写的很清楚了,用的是copy,就是指复制了

You’ll notice that the above get_instance() function is being passed by reference:

$CI =& get_instance();

This is very important. Assigning by reference allows you to use the original CodeIgniter object rather than creating a copy of it.




发表于 2015-6-11 13:53:24 | 显示全部楼层
ahcheqiu 发表于 2015-6-8 10:47
生成副本的意思是应该就是指复制了一份文档上写的很清楚了,用的是copy,就是指复制了You’ll notice tha ...

哈哈,其实我看懂了,只是你一说Unix的hardlink,我才扯出来了这么多。

本版积分规则