php函数参数默认按值传递,修改不影响外部变量;需改外部值时应在参数前加&声明引用,对象因存储标识符可直接修改属性但不可替换实例。

PHP函数里改不了变量值?默认是传值不是传引用
PHP函数参数默认按值传递,意味着函数内部修改变量,不会影响外部原始变量。这不是bug,是设计如此——除非你明确要改变外部变量,否则不该让函数“偷偷”改掉它。
常见错误现象:$name = "Alice"; changeName($name); echo $name; // 还是"Alice",而你期望输出"Bob"。
- 使用场景:需要在函数内修改数组结构、对象状态,或批量处理后返回新值
- 传值适合:计算、校验、生成结果等只读操作;安全、可预测
- 传引用适合:避免大数组/字符串复制开销,或需原地修改(如解析配置、递归构建树)
想让函数改外面的变量?加&符号声明引用参数
在函数定义时,在参数前加&,表示该参数接受引用。调用时无需额外操作,PHP自动绑定。
示例:
function appendItem(&$arr, $item) {
$arr[] = $item;
}
$myList = [1, 2];
appendItem($myList, 3);
// $myList 现在是 [1, 2, 3]
- 注意:不能对字面量或表达式传引用,比如
appendItem([1,2], 3)会报Only variables can be passed by reference - 函数内部对
$arr的unset()、reset()等操作,会影响外部变量 - PHP 8.1+ 对
&参数有更严格类型检查,若声明了类型(如array &$arr),传入非数组会报错
对象在PHP函数中天然“像引用”,但本质是传对象标识符
PHP 7+ 中,对象变量存储的是对象标识符(类似指针),函数内修改对象属性,外部可见;但若在函数内重新赋值整个变量(如$obj = new StdClass();),外部不受影响。
立即学习“PHP免费学习笔记(深入)”;
示例:
function modifyObj($obj) {
$obj->name = "changed"; // ✅ 外部可见
$obj = new StdClass(); // ❌ 外部仍指向原对象
}
- 不用加
&也能改属性,这是对象行为,不是引用传递 - 如果想在函数内彻底替换对象并让外部感知,必须用
&$obj - 数组不是对象,
array类型不享受此待遇——没加&就纯属复制
全局变量或global关键字?能不用就别用
用global $var或$GLOBALS['var']强行访问外部变量,看似绕过参数传递,实则破坏函数封装性,调试和测试都变困难。
- 常见错误现象:函数行为依赖未声明的全局状态,迁移或复用时莫名失效
- 性能上无优势,反而增加符号查找开销
- 替代方案更清晰:把依赖显式作为参数传入,哪怕多传一个
$config数组 - 唯一较合理场景:极少数遗留系统中无法修改函数签名,且确认该变量确实全局唯一、稳定










