【问题标题】:Closures don't work as class methods?闭包不能作为类方法工作?
【发布时间】:2011-12-14 09:55:59
【问题描述】:

我是否遗漏了什么或者闭包根本不能作为类方法工作?以此为例:

$foo = new stdClass();
$foo->bar = function() {
   echo '@@@';
};
$foo->bar();

似乎给我一个错误“致命错误:在第 X 行的 /blah/blah.php 中调用未定义的方法 stdClass::bar()”

这不应该调用放置在“bar”属性中的闭包吗?

【问题讨论】:

    标签: php closures


    【解决方案1】:

    是的,确实是这样。

    拨打bar的唯一方法是:

    $bar = $foo->bar;
    $bar();
    

    悲伤,但真实。

    同样值得注意的是,由于同样的效果,$bar 调用中没有$this(除非你将它作为函数参数传递给命名为$this)。

    编辑:正如 指出的,闭包内$this 的值与创建闭包时的范围值相同。 这可能意味着$this 可能在两种情况下未定义:当作用域是全局 PHP 作用域时,或者当作用域来自静态上下文时。然而,这意味着理论上您可以提供正确的实例:

    class Foo {
        public $prop = 'hi';
        function test(){
            $this->bar = function(){
                echo $this->prop;
            }
    
            $bar = $this->bar;
            $bar();
        }
    }
    
    $foo = new Foo();
    $foo->test();
    

    另外,似乎有了一些类魔法,你也可以实现$this->bar()

    class Foo {
        // ... other stuff from above ...
        public function __call($name, $args){
            $closure = $this->$name;
            call_user_func_array( $closure, $args ); // *
        }
    }
    

    [*] 注意call_user_func_array 的速度非常很慢。

    哦,这仅适用于 PHP 5.4。在此之前,闭包中没有 $this :)

    另外,你可以在here看到它。

    【讨论】:

    • 咕。这会很快改变吗?
    • $this 在闭包中给我一个错误,即它在非对象上下文中使用,即使它是在对象中定义并在对象中调用的。
    • 您使用的是 PHP 5.4 吗?请尝试我在 viper7 上的演示。
    • @dqhendricks 你运气不好:/
    • 也可以使用->invoke() 调用闭包类成员。 stackoverflow.com/questions/4535330/…
    【解决方案2】:

    方法和字段是完全分开的;事实上,你甚至可以拥有同名的方法和字段:

    <?php
    class foo{
        function bar() { echo "hello\n"; }
    }
    $object = new foo;
    $object->bar = 1;
    $object->bar(); // echoes "hello"
    ?>
    

    这解释了为什么您的语法无法创建“真实”方法。

    【讨论】:

    • 我没想到它会创建一个“真实”的方法,但我确实希望它能让我在属性中调用闭包。
    • @dqhendricks:那么调用方法bar和调用存储在字段bar中的函数在语法上没有区别。所以你在做什么是模棱两可的
    • 你是对的。这会造成混乱。然而,在我的特定情况下,这将是一个非常有用的功能,但我找到了一种在没有它的情况下实现相同功能的方法。
    猜你喜欢
    • 2015-02-18
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 2023-03-13
    • 2010-11-26
    相关资源
    最近更新 更多