PHP变量赋值方式有哪些_PHP变量赋值操作【详解】

3次阅读

php变量赋值绝大多数是值拷贝,但对象、资源等类型默认按引用语义处理;$a = $b对普通变量是深拷贝,$obj1 = $obj2是对象标识符复制,强制值拷贝需clone,强制引用需&。

PHP变量赋值方式有哪些_PHP变量赋值操作【详解】

PHP变量赋值是值拷贝还是引用?

绝大多数情况下,PHP变量赋值是值拷贝(copy by value),但对象、资源和某些扩展类型默认按引用语义处理。这不是“有时引用有时值”,而是由类型决定的底层行为。

常见错误现象:foreach 中修改数组元素却没生效;函数内改了数组,外部没变;对象属性修改却跨作用域生效。

  • $a = $b 对普通变量(intStringArray)是深拷贝副本,互不影响
  • $obj1 = $obj2 实际是“对象标识符”复制,两个变量指向同一对象实例
  • 想强制值拷贝对象,得用 clone $obj;想强制引用赋值,用 $a =& $b
  • PHP 7+ 的 array 赋值在写时才真正复制(Copy-on-Write),性能友好但观察不到中间状态

什么时候必须用 & 符号做引用赋值?

只有当你明确需要两个变量共享同一内存地址,并且后续任意一方修改都同步反映到另一方时,才该用 &。它不是优化手段,而是语义需求。

典型使用场景:函数内修改传入的数组结构、构建链式数据结构、避免大数组重复拷贝(但需谨慎)。

立即学习PHP免费学习笔记(深入)”;

  • 函数参数中用 &$arr 表示“允许函数修改原始数组”,调用时不能传字面量如 func(&[1,2])(会报 Only variables can be passed by reference
  • $a =& $b 后,unset($b) 不影响 $a,因为引用关系已建立,$a 持有独立引用
  • foreach 中的值加 & 可直接修改原数组:foreach ($arr as &$v) { $v *= 2; },但循环结束后记得 unset($v),否则 $v 仍引用最后一个元素,下次赋值可能出错

数组赋值的坑:特别是多维数组和 unset 后的行为

数组看似简单,但嵌套层级一深,赋值和销毁就容易误判“谁变了谁没变”。根本原因在于 PHP 数组是 HashTable 实现,不是纯值类型

常见错误现象:unset($arr['key']) 后,$new = $arr 还包含被删的键;二维数组 $a['x']['y'] = 1 后,$b = $a 修改 $b['x']['y'] 却不影响 $a(因为子数组仍是值拷贝)。

  • 单层数组赋值 $b = $a 是完整副本,unset($a['k']) 不影响 $b
  • 但若 $a['nested'] = &$someVar,那 $b = $a 后,$b['nested'] 依然引用 $someVar —— 引用关系随变量一起复制
  • array_merge()+ 合并数组时,键冲突处理不同:$a + $b 保留左数组键,array_merge($a, $b) 用右数组覆盖左数组同名数字键,字符串键则后者覆盖前者

PHP 8.1+ 属性提升与只读类对赋值的影响

启用 readonly 类或属性后,“赋值”变成一次性操作,后续任何写入都会抛出 Fatal Error: Cannot modify readonly Property。这不是语法糖,是运行时强约束。

这改变了你对“变量可变性”的直觉,尤其在封装配置、DTO 或实体类时。

  • class Config { public readonly string $host; }构造函数里赋一次,之后 $cfg->host = 'x' 直接崩溃
  • readonly 数组或对象属性,其内部元素/属性仍可变(除非它们自己也是 readonly),比如 public readonly array $data; 允许 $obj->data[] = 1
  • 想彻底冻结整个结构,得组合用 readonly + array_is_list() + 自定义不可变逻辑,PHP 不提供 deep readonly

事情说清了就结束。最常被忽略的是:你以为在改值,其实改的是引用;你以为赋了值,其实只是挂了个钩子;你以为加了 readonly 就万事大吉,结果子元素还在悄悄变。

text=ZqhQzanResources