下面的代码使用存储在属性$ prop中的字符串"rand"来调用rand()作为变量函数,使用$ function作为临时局部变量.
class C
{
private $prop = "rand";
public function execute()
{
$function = $this->prop;
echo $function();
}
}
$c = new C();
$c->execute();
Run Code Online (Sandbox Code Playgroud)
这是有效的,但我需要使用一个语句并避免使用临时变量来调用存储在$ this-> prop中的变量函数.
我没有运气
echo $this->prop();
Run Code Online (Sandbox Code Playgroud)
因为它实际上调用了不存在的方法prop(),并且在任何情况下它都不是我想要做的.
由于$ this-> prop实际上是一个字符串,我尝试了以下内容,但它产生了语法错误:
echo ($this->prop)();
Run Code Online (Sandbox Code Playgroud)
我也试过了
echo call_user_func($this->prop);
Run Code Online (Sandbox Code Playgroud)
虽然它可以完成工作,但它不是我的选择,因为它不是一个可变函数.
看起来变量函数只能使用局部变量作为函数名.
有没有人知道使用类属性作为函数名直接调用变量函数的方法,避免使用本地临时变量和call_user_func()的用法?
编辑: 我理解你的困惑,因此我将解释使用call_user_func时出了什么问题.
我只是在探索变量函数提供的机会,这似乎比变量变量提供的机会少.
让我们尝试使用变量变量将其最简单的形式.
假设我们有一个函数f(),它返回字符串"something"
function f() {
return "something";
}
Run Code Online (Sandbox Code Playgroud)
然后是包含字符串"something"的类属性
$this->prop = "something";
Run Code Online (Sandbox Code Playgroud)
$ something是一个局部变量
$something = "I am a local variable";
Run Code Online (Sandbox Code Playgroud)
然后以下所有语句都将起作用:
$r = ${"something"};
$r = ${$this->prop};
$r = ${f()};
Run Code Online (Sandbox Code Playgroud)
我的个人结论:无论字符串"东西"如何获得; 用大括号{}围绕它,并在前面添加美元符号$,将其视为变量.相当flessibe.
让我们尝试相同的变量函数
现在我们有一个函数f()返回字符串"rand"
function f() {
return "rand";
}
Run Code Online (Sandbox Code Playgroud)
然后是包含字符串"rand"的类属性
$this->prop = "rand";
Run Code Online (Sandbox Code Playgroud)
另一方面,变量函数不允许将字符串后跟括号()视为函数调用.
$r = "rand"(); // Produces a syntax error, unexpected '()' after a string
$r = $this->prop(); // Calls the 'prop()' method, which does not exist
$r = f()(); // Again a syntax error, unexpected '()' after the function f()
Run Code Online (Sandbox Code Playgroud)
我必须得出结论,变量函数总是需要运行局部变量 :(
您需要实现一个魔术__call方法,如下所示:
class C
{
private $prop = "execute";
public function __call($method, $args)
{
if($method == "prop") // just for this prop name
{
if(method_exists($this, $this->prop))
return call_user_func_array([$this, $this->prop], $args);
}
}
public function execute ($s){
echo '>>'.$s.'<<';
}
}
$c = new C;
$c->prop(123);
Run Code Online (Sandbox Code Playgroud)