php 返回引用的疑问

2016-11-16 22:49:30 +08:00
 silenceeeee
class a{

    public $a = 5;

}

function &load_class(){

    static $_classes = array();
    
    if (!isset($_classes['a'])){
    
        $_classes['a'] = new a();
        
    }
    return $_classes['a'];
    
}

$obj = &load_class();

echo $obj->a;

$obj->a = 1;

$obj2 = &load_class();

echo $obj2->a;

echo PHP_EOL;

exit;

这段代码为什么会输出: 51 而不是: 55 ?

3346 次点击
所在节点    PHP
32 条回复
haiyang416
2016-11-17 13:45:06 +08:00
@Sunyanzi 确实没有开启 E_DEPRECATED ,开启后可以看到提醒。

不过弃用提醒并不影响代码的执行,我其他关于 scope 的回答是针对 13 楼楼主问 test_global_ref 执行后 $obj 为什么仍然是 NULL ,与 Assigning the return value of new by reference 这个特性被弃用无关,可以把 &new stdClass 换作其他的类型,比如对一个字符串的引用。如果我这部分理解有误,希望可以给出正确的回答,我很愿意详细了解具体的缘由。
haiyang416
2016-11-17 13:57:16 +08:00
Zzzzzzzzz
2016-11-17 14:15:35 +08:00
php4 里赋值是复制, 所以才需要&load_class, php5 除了基本类型是写时复制外返回引用, 这种已经不用了.

php5 没比 php4 晚发布多久, 但早期主要充当试验田, 社区想直接跨到 6 , 后来计划改了, 所以到了 5.2~5.3 期间才逐渐开始在生产环境铺开, 因此很多 php5 中早期产生的代码里会保留很多兼容 php4 的写法, 这种东西不用看了.
jhdxr
2016-11-17 18:23:00 +08:00
@silenceeeee 官方文档其实完全足以解释这个问题, 前提是你看懂了每一个字,参见: https://tech.jhdxr.com/archives/explanation-of-global-or-static-trap-in-php/
jhdxr
2016-11-17 18:29:50 +08:00
@Sunyanzi @Zzzzzzzzz 那段示例代码之所以会报错只是因为它的确使用了一个过时并且已经被移除了的特性,然而关于 global/static 的原理到现在(PHP 7)也依然没有变化。 此外, global 目前的确一般情况不再使用,但 static 还是丢不掉的。。。
NoobPhper
2016-11-17 20:01:52 +08:00
楼主引用和引用计数要分开
silenceeeee
2016-11-17 20:04:42 +08:00
@jhdxr 你说的这个我早就看懂了 就如你博客中说的一样 这个层面其实好理解 问题在于对象赋值与对象引用赋值 你去看下官方文档中对象与引用相关内容 如果有人愿意探讨这个问题可以与我电话联系 感觉码子效率太慢。很难表述 我个人感觉是理解不了这个问题了
silenceeeee
2016-11-17 20:48:41 +08:00
@NoobPhper 引用计数指的是?
NoobPhper
2016-11-17 21:31:22 +08:00
@silenceeeee sorry 是我粗心了了 没仔细看,这道题无关 引用 与 static 关键字 ,其实更像单例模式或者就是单例模式。
obj2 和 obj1 用的是同一个被实例化的类。 你可以 var_dump $obj 来看 可以看到类似这样的状态

```
/Users/laputa/Desktop/pattern/static.php:24:
class a#1 (1) {
public $a =>
int(5)
}
5
/Users/laputa/Desktop/pattern/static.php:31:
class a#1 (1) {
public $a =>
int(1)
}
```

a# 后面的数字是在同一生命周期下被实例化的对象个数 同时也可以认为是标记 ,从同一个 1 可以看出 他们引用的是同一实例化对象 . 希望能帮到你
NoobPhper
2016-11-17 21:32:58 +08:00
@silenceeeee 对你误导了 是在对不起
jhdxr
2016-11-17 22:48:34 +08:00
@silenceeeee 你先定义一下『对象赋值』与『对象引用赋值』
lisir
2016-11-18 10:28:35 +08:00
如果觉得饶了,可以看看这个(很清楚明了的): http://www.jb51.net/article/51985.htm

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/321049

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX