最近在review团队代码时,发现有些小崽子还在用字符串拼接这种上古写法,看得我血压直接拉满。今天就来聊聊PHP中花括号${}的正确打开方式,保证让你写出更优雅的代码。
首先得搞清楚,${}在PHP里主要有三种玩法。第一种是变量解析,在双引号字符串里可以直接插变量:
$name = '二狗子';
echo "你好啊${name},今天搬砖了吗?";
这种写法比字符串拼接清爽多了,不用再写一堆烦人的.号。但要注意,花括号里不能直接写表达式,比如${1+1}这种骚操作是会报错的。
第二种用法是可变变量,这个就有点意思了:
$foo = 'bar';
$bar = '牛逼';
echo ${$foo}; // 输出"牛逼"
看到没?这就像俄罗斯套娃,变量里套变量。不过玩这个要小心,搞不好就会翻车。比如:
$var = '不存在的变量';
echo ${$var}; // Notice级别的错误就来了
所以老司机都会先isset检查一下:
isset(${$var}) ? ${$var} : '默认值';
第三种是类属性访问,这个在框架里特别常见:
class User {
public $name = '王铁柱';
}
$user = new User();
$property = 'name';
echo $user->{$property}; // 输出"王铁柱"
这个技巧在写ORM的时候特别好用,可以动态访问属性。但要注意私有属性这么玩会直接GG,PHP会毫不留情地抛出致命错误。
说到坑,不得不提一个经典bug。有次线上出事故,查了半天发现是这么段代码:
$data = ['id' => 123];
$key = 'id';
echo "ID是:${$data[$key]}";
看出来问题了吗?正确的写法应该是:
少了个$符号,直接导致PHP尝试把数组值当成变量名来解析,结果当然是毛都没找到。这种错误在代码审查时特别容易漏掉,建议用IDE的语法检查插件。
再来看个实际项目中的例子。我们有个配置系统需要动态加载不同模块:
$modules = ['user', 'order', 'payment'];
foreach($modules as $module) {
$config = ${$module.'_config'} = require "config/{$module}.php";
}
这里用可变变量动态创建了$user_config、$order_config等变量。虽然看起来骚,但其实有个更好的方案是用extract函数:
$configs = [];
$configs[$module] = require "config/{$module}.php";
}
extract($configs);
这样代码更清晰,而且不容易出现变量污染的问题。
性能方面,有人测试过${}和直接变量访问的差异。在PHP7+环境下,两者的性能差距可以忽略不计。但在循环几百万次的情况下,直接访问变量还是快那么一丢丢。不过说实话,这种优化属于典型的"过早优化",除非你是写框架,否则真没必要纠结。
最后分享个冷知识:在heredoc语法中,${var}和{$var}的解析规则是不一样的。比如:
$var = 'test';
echo <<
${var}和{$var}的区别
EOT;
这个例子中两者输出相同,但在复杂表达式时会有差异。建议统一使用{$var}的写法,兼容性更好。
记住,代码是写给人看的,偶尔装逼可以,但别玩过头。上次见有人写出${${${$var}}}这种代码,直接被团队祭天了。保持代码可读性,你的同事会感谢你的。