在分析Oauth 2.0的的一个开源服务端代码时,因为我是用netbeans来查看,在边上给了一些黄色感叹号的提示信息,提示变量没有初始化。我仔细查看上下文,确实没有初始化,但是代码执行是准确的,非常奇怪。后来我注意到一个方法extract,这才找到原因所在。
php中的extract方法可以将数组中的数据转换到当前上下文环境,其中key作为变量名,value作为变量的值。示例代码:
$user = array(
'name' => 'tom'
,'age' => 20
);
extract($user);
echo $name; //输出tom
echo $age; //输出20
但是这样获取变量的方式比较隐秘,用一句俗话来说就是藏的很深,我个人认为不利于代码阅读。比如下面代码:
$name = 'anny';
$user = array(
'name' => 'tom'
);
extract($user);
echo $name; //输出tom
$name在初始的时候被赋值为anny,但是经过extract后,$name就变成了tom,初始的赋值被覆盖了。这边代码比较简单还容易看的出来,如果是在比较复杂的代码里,有时就会纳闷了——到底哪里对$name进行重新赋值了?为什么搜索$name这个变量都搜索不到重新赋值的地方?
针对变量被覆盖这个问题,extact提供了另外两个参数,来避免这个问题,看下面代码:
$name = 'anny';
$user = array(
'name' => 'tom'
);
extract($user, EXTR_SKIP); //增加了EXTR_SKIP这个参数
echo $name; //输出anny
这边加入了一个新参数EXTR_SKIP,表示不覆盖原有的变量。
也可以使用EXTR_PREFIX_ALL来为转换出来的变量名称增加前缀,看下面代码:
$name = 'anny';
$user = array(
'name' => 'tom'
);
extract($user, EXTR_PREFIX_ALL, 'user');
echo $name; //输出anny
echo $user_name; //输出tom
前缀和数组键名之间会自动加上下划线。
第二个参数还有其它的模式,详情可以参考官方手册。尽管extract提供了其它参数使得运用多样化,但是我个人还是不建议使用。如果要使用的话,尽量保证上下文代码简短,这样也方便阅读代码。