【问题标题】:PHP: assign function to class methodPHP:将函数分配给类方法
【发布时间】:2015-02-24 00:16:37
【问题描述】:

如何在 PHP 中将函数分配给类中的方法?我尝试了以下方法:

class Something{
    public function __construct(){
        $functionNames = array('foo', 'bar')

        $variable = 'blablabla';

        foreach($functionNames as $functionName){
            if(method_exists($this, $functionName))
                continue;

            $this->{$functionName}() = function($params){ //should create the methods "foo" and "bar"
                echo $variable; //should echo 'blablabla' (I know that the variable was declared outside this function, but how can I access it anyway?)
            }; //the error points to here
        }
    }
}

但是这段代码给了我这个错误:

Fatal error: Can't use method return value in write context

有谁知道我如何将匿名函数分配给类方法,同时仍然能够访问该函数之外的变量?

【问题讨论】:

  • 我认为在 PHP 中这是不可能的。我认为您必须实例化一个对象或让一个函数返回一些将某些东西分配给变量的东西。不过,这不是一个坏问题。
  • 你不能在类构造函数中返回。它会抛出一个错误。 php.net/manual/en/language.oop5.decon.php
  • @versalle88 是的,这是真的......我实际上有一个 foreach 循环,return; 是一个continue;,但我决定稍微简化一下代码,因为(我认为)它是没必要。不过我会编辑它
  • 虽然还是不行,但是在赋值匿名函数的时候,不要在变量上使用大括号:$this->{$functionName[0]} = function($params){
  • 我不明白这是如何工作的。构造函数返回后,$variable 的值将存储在哪里?

标签: php function oop methods


【解决方案1】:

你正在做foreach($functionNames as $functionName){ 这意味着$functionName 是一个字符串,而不是一个数组。所以,不要使用$functionName[0]

method_exists 有 2 个参数。一个是对象,另一个是方法名。应该是:

method_exists($this, $functionName)

至于创建函数,您不需要=left 侧的()。应该是:

$this->$functionName = function($params) use($variable){
    echo $variable;
};

use($variable) 用于告诉 PHP 在函数中使用该变量。这就是 PHP 中闭包的工作方式,它与其他语言不同。

所以,你的类应该是这样的:

class Something{
    public function __construct(){
        $functionNames = array('foo', 'bar');

        $variable = 'blablabla';

        foreach($functionNames as $functionName){
            if(method_exists($this, $functionName)){
                continue;
            }

            $this->$functionName = function($params) use($variable){
                echo $variable;
            };
        }
    }
}

这里的问题是,在这种创建函数的方式中,你实际上并没有创建一个类方法,而是创建了一个包含函数的类变量。

所以,你需要这样称呼它:

$test = new Something;
$foo = $test->foo;

$foo('abc');

你不能只做$test->foo('abc');

编辑:您可以做的另一件事是使用 PHP 的 __call“魔术方法”。这将在您执行->funcName() 时运行,无论该方法是否存在。使用该方法,您只需检查调用的方法是'foo' 还是'bar'。看这个例子:

class Something{
    private $variable;

    public function __construct(){
        $this->variable = 'blablabla';
    }

    public function __call($name, $params=array()){
        if(method_exists($this, $name)){
            // This makes sure methods that *do* exist continue to work
            return call_user_func(array($this, $name), $params);
        }
        else{
            $functionNames = array('foo', 'bar');

            if(in_array($name, $functionNames)){
                // You called ->foo() or ->bar(), so do something
                // If you'd like you can call another method in the class
                echo $this->variable;
            }
        }
    }
}

有了这个,现在您可以执行以下操作:

$test = new Something;
$test->foo('abc');  // Will echo "blablabla"

【讨论】:

    猜你喜欢
    • 2018-02-07
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    相关资源
    最近更新 更多