一、概要
- php的变量声明
- 可变性体现在哪
- 避免可变变量歧义问题
- 可变性意义何在
二、php变量声明
简单的php变量声明如下:
<?php
$a = 'hello';
echo $a; // 'hello'
有时在class 中声明变量, 可能会遇到如下的声明:
class Cls
{
var $a = 1;
}
var 为 php4.0声明类成员变量 的关键字, php5.0以后已废弃,详见stackoverflow该提问
三、变量可变性体现
请看如下代码:
$hello = "amazing !";
$a = 'hello';
echo $$a; // 'amazing !'
可以看到,变量值还可以进一步作为变量名 !!!
看看另一个例子:
function func()
{
echo "amazing !";
}
$test = "func";
$test();
天哪噜,变量值解析后还可进一步作为函数名调用函数 !!!
放眼到class中,也是一样:
class Cls
{
public $a = "amazing !";
function func()
{
echo "Cls func";
}
}
$b = "a";
$f = "func";
$className = "Cls";
$obj = new $className(); //成功实例化了一个Cls对象
echo $obj->$b; // 输出 $obj->a 即: 'amazing !'
$obj->$f(); // 成功调用 $obj->func();
我们可以看到:php变量值在一定条件下可以进一步作为 其他变量的名称,包括普通变量(variables),函数(function)或方法(method), 类(class)。
四、可变变量可能引发的问题
当将可变变量应用于数组,稍不注意,可能引发一个歧义问题(ambiguity problem) , 就是当写下$$s[0]
时,解析器需要知道是想要 $s[0]
作为一个变量呢,还是想要 $$s
作为一个变量并取出该变量中索引为 [0]
的值。解决此问题的语法是,对第一种情况用 ${$s[0]}
,对第二种情况用 ${$s}[0]
。请参看下代码:
<?php
$a = 'i am a';
$aaa = 'i am aaa';
$s = "aaa";
echo $$s[0]; // i am a
echo ${$s[0]}; // i am a
echo ${$s}[0]; // i
五、so ,意义何在?
变量可变性本质上是反射机制的体现,直接的优势就是众多设计模式(如工厂类设计模式)的运用,反射机制的优势,举一个例子:
存在100个类声明,我们需要根据客户端需要创建不同的对象实例
class Cls1
{
}
class Cls2
{
}
...
class Cls100()
{
}
// 方式1
function createObject($classType)
{
switch ($classType)
{
case 1:
return new Cls1();
case 2:
return new Cls2();
...
case 100:
return new Cls100();
}
}
// 方式2
function createObject($classType)
{
return new 'Cls' . $classType();
}
很明显,如果不支持反射(即字符串无法被进一步解析成类名称), 有两个缺点:
- 每拓展增加一个类,如Cls101, 都需改动createObject的代码,增加一个判断分支,不符合设计模式中的开放封闭原则
- 垃圾代码量太多
就是因为支持反射,所以简洁的方法2实现成了可能,大大解放劳动力,2333。
关于 反射机制, 工厂模式,开放封闭原则,可以参考资料: