在上一篇文章中,我们学习了关于引用和引用转值的相关知识。我们知道PHP中没有纯引用(指针)。不管是对象还是变量赋值了引用符号&,都是对符号表的引用。今天,我们要学习的是另一种形式的引用:弱引用。什么是弱引用弱引用允许程序员保留对对象的引用,而不会阻止对象被销毁;它们对于实现类似缓存的结构很有用。这是比较官方的解释。从这个描述可以看出,弱引用也是引用的一种形式,但是如果我们销毁了原来的对象,那么弱引用对象也会被销毁,就像普通的值对象赋值一样。如果你还没有看过前面的文章,或者对PHP中的引用不熟悉的朋友可能需要进一步了解PHP中的引用。接下来我们直接看例子。弱引用$obj=newstdClass;$weakref=$obj;var_dump($weakref);//对象(stdClass)#1(0){//}unset($obj);var_dump($weakref);//对象(stdClass)#1(0){//}$obj1=newstdClass;$weakref=WeakReference::create($obj1);var_dump($weakref->get());//object(stdClass)#2(0){//}unset($obj1);var_dump($weakref->get());//NULL$weakref=WeakReference::create(newstdClass);var_dump($weakref->get());//NULL第一个对象\$obj我们做一个直接赋值引用,这是PHP默认的对象赋值。此时,$weakref持有对象符号表的引用。当我们unset()$obj时,$weakref仍然可以正常使用。即$weakref对$obj原始对象的内存引用仍然保持。无论我们如何unset()原始的$obj,都只是切断了$obj的引用符号表,对真正的对象没有影响,垃圾回收器也不会完全回收最原始的$obj对象内容。我们使用的第二个对象是通过WeakReference的create()方法创建的弱引用。当我们销毁$obj1时,$weakref也会变成NULL。这就是弱引用的用途!它可以让垃圾回收器正常回收,它可以避免循环引用造成的内存泄漏,它可以让引用表现得像C中的指针操作。最后一段代码是我们直接在WeakReference::create()中使用new来创建对象。这种形式是不可接受的,将始终返回NULL。因为弱引用是由变量创建的,它指向的是原始对象的符号表,而变量和对象之间的符号表连接是弱引用关心的,它会根据状态判断当前状态的符号表。如果原来的对象变量切断了与符号表的联系,那么弱引用变量也会同步切断,这样垃圾回收器就可以正常清理没有任何引用计数的对象。注意,这里需要注意的是,上面的测试代码必须在PHP7.4及以上版本有用,而WeakReference类是PHP7.4新增的。之前的版本需要安装WeakRef扩展来实现弱引用的能力。有关详细信息,请参阅以下链接中的相关文件。测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202006/source/%E5%AD%A6%E4%B9%A0PHP%E5%BC%B1%E5%BC%95%E7%94%A8%E7%9A%84%E7%9F%A5%E8%AF%86.php参考文档:https://www.php.net/manual/en/class.weakreference.phphttps://www.php.net/manual/zh/book.weakref.php各媒体平台均可搜索【硬核项目经理】
