如何在方法中定义的匿名函数内使用`self::`访问类常量?

17

我想从匿名函数中使用self来访问类常量。

class My_Class {    
    const  CLASS_CONSTANT = 'test value';
    private function my_function(){     
        $lambda_function = function(){
            echo self::CLASS_CONSTANT;
        };
        $lambda_function();
    }
}

当我尝试运行这段代码时,我收到了以下错误提示:

Fatal error: Cannot access self:: when no class scope is active in ...

是否可以将父类传递给此匿名函数的作用域中?使用use语句可行吗?

4个回答

18

>> PHP 5.4+的所有版本测试在3v4l上 <<

PHP 5.4+方法:

自从PHP 5.4以来,这变得更加简单了,其中$this不再是脏的:

class My_Class {
    const CLASS_CONSTANT = 'test value';

    private function my_function() {
        $lambda_function = function() {
            // $this is actually inherited from the parent object, so
            // you don't even need a use() statement
            echo $this::CLASS_CONSTANT;

            // Or just use self, that's inherited too
            echo self::CLASS_CONSTANT;
        };
        $lambda_function();
    }
}

5.4版本之前的方法:

将匿名函数变成闭包,通过在函数中引入作用域变量并从中调用常量:

class My_Class {
    const CLASS_CONSTANT = 'test value';
    private function my_function() {
        $self = $this;
        $lambda_function = function() use ($self) { // now it's a closure
            echo $self::CLASS_CONSTANT;
        } // << you forgot a ;
        lambda_function(); // << you forgot a $
    }
}

很遗憾,您目前还不能使用use ($this)。他们正在处理这个问题。我预计它将在PHP >= 5.4中可用。


1
在匿名类中调用静态方法如 static::Func() 怎么样?(是的,My_Class::Func() 可以工作,但这不是重点)对于静态函数,有哪个 $this 等效的东西? - Pacerier
你可以调用 $self::func(),即使它是受保护或私有的,因为你是从类本身的上下文中调用它。不过我并不完全确定...试一下吧。$object::static() 是你的好朋友。 - Rudie
1
在php 5.5中,可以在匿名函数内部使用self而无需使用use关键字。 - Jan Wy

8
据我所知,匿名函数只是函数,而不是类方法,因此作用域失效。您可以将常量作为参数传递或使用My_Class::CLASS_CONSTANT。

如果您不想通过类名引用类,可以使用魔术常量__CLASS__来有效地替换lambda函数中的self - N.B.
3
可以这样做,我可能会使用它。但需要两行代码:$class_name = __CLASS__; $class_name::CLASS_CONSTANT; 因为 __CLASS__::CLASS_CONSTANT; 无法正常工作。 - steampowered

1

在匿名函数内访问self是无效的。你应该使用My_Class::CLASS_CONSTANT代替self引用。


private function my_function() use ($any_variable){ ... } 对于除了 $this 之外的任何变量都有效。为什么它不能与 $this 一起使用呢? - steampowered
因为 PHP 的开发人员在正确实现此功能时遇到了困难,据我所知。但它将会在即将发布的 PHP 版本中可用(5.4.0)。 - Berry Langerak

1

不,这是不可能的。同样地,您也不能将$this绑定到匿名函数。但是只需传递必要的值即可解决问题,对吧?

<?php
class My_Class {
    const  CLASS_CONSTANT = 'test value';
    private function my_function(){     
        $lambda = function( $yourConstant ){
            return $yourConstant;
        };

        return $lambda( self::CLASS_CONSTANT );
    }

    public function test( ) {
        return $this->my_function( );
    }
}

$class = new My_Class( );
echo $class->test( ); // 'test value'

附注:没有什么可以阻止您将$this变量传递到匿名函数的"use"部分。 您只需要将其分配给中介变量,例如$that = $this,然后function() use($that) {},就会引用当前对象。 - Victor Farazdagi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接