使用类属性作为函数名称调用变量函数

时间:2015-01-23 16:34:01

标签: php

以下代码使用字符串" rand"存储在属性$ prop中,通过使用$ function作为临时局部变量来调用rand()作为变量函数。

class C
{
    private $prop = "rand";

    public function execute()
    {
        $function = $this->prop;
        echo $function();
    }
}

$c = new C();
$c->execute();

这是有效的,但是我需要使用一个语句并避免使用临时变量来调用存储在$ this-> prop中的变量函数。

我没有运气

echo $this->prop();

因为它实际上调用了不存在的方法prop(),在任何情况下它都不是我想要做的。

由于$ this-> prop实际上是一个字符串,我尝试了以下内容,但它产生了语法错误:

echo ($this->prop)();

我也试过

echo call_user_func($this->prop);

虽然它完成了工作,但它不是我的选择,因为它不是一个可变函数。

似乎变量函数只能使用局部变量作为函数名。

有没有人知道使用类属性作为函数名直接调用变量函数的方法,避免使用本地临时变量和call_user_func()的使用?

修改 我理解你的困惑,因此我将解释使用call_user_func的错误。

我正在探索变量函数提供的机会,这似乎比变量变量提供的机会少。

让我们尝试使用变量变量,它是最简单的形式。

假设我们有一个函数f(),它返回字符串"某些东西"

function f() {
  return "something";
}

然后是一个包含字符串""

的类属性
$this->prop = "something";

$ something是一个局部变量

$something = "I am a local variable";

然后以下所有陈述都有效:

$r = ${"something"};
$r = ${$this->prop};
$r = ${f()};

我的个人结论:无论字符串"是什么"已经获得;用大括号{}围绕它,并在前面添加美元符号$以将其视为变量。 很好的flessibe。

让我们尝试相同的变量函数

现在我们有一个函数f(),它返回字符串" rand"

function f() {
  return "rand";
}

然后是包含字符串" rand"

的类属性
$this->prop = "rand";

另一方面,变量函数不允许将字符串后跟括号()视为函数调用。

$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()

我必须得出结论,变量函数总是需要运行局部变量 :(

3 个答案:

答案 0 :(得分:3)

您需要实现一个神奇的__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);

答案 1 :(得分:2)

在PHP的语法中,它确实感觉像是一个明显的遗漏。 (虽然字面意思我认为它们是变量函数,而不是属性函数!?)我可能希望以下“大括号”语法起作用,但它没有' t,Parse error: syntax error, unexpected '{' in ...

echo {$this->prop}();

但是,使用变量函数语法比其他方法有很多好处。变量函数比call_user_func() / call_user_func_array()更快,并且原生支持pass-by-reference,而不是call_user_func_array()的“特殊情况”调用时间传递引用(这是在所有其他情况下弃用。)

__call魔术方法(上面)的另一种选择,就是相对较慢,就是简单地使用一个包装器方法,你传递函数/方法名称并在包装器中使用变量函数方法

以最简单的形式:

function callUserFunc($callable) {
    return $callable();
}

由于性能优势(使用call_user_func_array()),几个框架实现了类似的“辅助”方法,允许可变数量的参数。其他问题/答案更深入,涵盖了一些性能基准:Calling a function with explicit parameters vs. call_user_func_array()

答案 2 :(得分:1)

如果有人想知道,从PHP 7开始我们就会立即调用函数表达式。

虽然这个特殊情况没有记录,但它实际上适用于以下示例:

class Test {

    private $func = "strtolower";

    public function testFunc() {
        return ($this->func)("ALPHABET");
    }
}

$t = new Test();

echo $t->testFunc(); //echoes alphabet in PHP 7+ error in anything below

这可以在https://3v4l.org/JiuIF

中看到