php中$obj存储的是指向对象的引用标识符(非对象本身),赋值仅复制标识符,unset($obj)仅解除绑定,clone才创建新实例,==比较属性值,===判断是否同一实例。

PHP里 $obj 到底存的是什么
它不是对象本身,而是一个指向对象的“引用标识符”(类似指针ID),PHP内部用这个标识符在内存中找到真正的对象数据。所以$a = $b 对象赋值时,只是复制了这个标识符,不是复制整个对象。
- 常见错误现象:
unset($a)后$b仍可正常使用 —— 因为对象实例还在,只是少了一个引用 - 使用场景:需要共享状态时(如配置容器、数据库连接),这种“默认引用语义”是合理的;但想深拷贝时就容易出错
- 性能影响:赋值开销极小,无论对象多大;但所有引用都指向同一块内存,修改属性会相互影响
什么时候会真正复制对象(深拷贝)
只有显式调用 clone 才会创建新实例。不写 __clone() 方法的话,PHP 默认做浅拷贝 —— 对象属性里的标量和不可变类型被复制,但嵌套对象、数组里的对象仍共享引用。
- 常见错误现象:克隆后修改
$obj2->data->id,发现$obj1->data->id也变了 - 实操建议:如果对象含其他对象或资源,必须手动实现
__clone(),并在里面clone $this->nestedObj - 注意点:
clone不触发__construct(),也不能传参,初始化逻辑得挪到__clone()里
== 和 === 比较对象时的区别
== 判断两个对象是否“内容相等”(属性名+值完全一致,且类相同);=== 判断是否为同一个实例(即引用标识符相同)。
- 常见错误现象:
if ($a == $b)返回 true,但$a->prop = 1并没改$b->prop—— 它们其实是不同对象 - 使用场景:
===适合判断单例是否已初始化;==少用,因为不递归比较嵌套对象,容易误判 - 兼容性提醒:PHP 8.0+ 对
==的行为更严格,类名不同直接 false,不再尝试属性对比
对象变量和 unset()、NULL 赋值的区别
unset($obj) 是断开变量名和对象标识符的绑定;$obj = null 是把变量设为 null 值,但原绑定关系还在(直到垃圾回收清理)。
立即学习“PHP免费学习笔记(深入)”;
- 常见错误现象:循环中
$item = null后继续用$item,可能意外复用上一轮的对象引用(尤其 foreach 引用赋值时) - 实操建议:要确保对象释放,优先用
unset($obj);若需中间置空再复用,明确重新 new 或赋值 - 容易被忽略的地方:对象内有循环引用(比如 A→B 且 B→A)时,仅
unset不足以立即释放内存,得靠 GC 周期











