类方法中的PHP匿名函数隐藏类名(希望使用类似self的东西来寻址类名)


PHP anonymous function within class method hides class name (would like to use something like self to address the class name)

在下面的PHP代码中,一行代码被注释掉(请参阅注释),并替换为下一行代码,目的是在不指定类名的情况下实现相同的效果。然而,我试图在代码中消除的显式类名对函数是隐藏的。如何在不象原始代码中那样明确地写下类名的情况下修复此问题?

class EmbeddedTriplets {
  private $count;
  private $values;
  function __construct($value = 0, $count = 1) {
    $this->count = $count;
    $this->values = array($value, $value, $value);
  }
  public function getEmbeddedOutput() {
    if ($this->count > 0) {
      $output = $this->values;
      $func = function($value) {
        //return new EmbeddedTriplets($value);
        // HERE INSTEAD OF THE LINE ABOVE I WOULD LIKE TO WRITE ACHIEVE THE SAME THING
        // BUT WITHOUT SPECIFYING THE CLASS NAME (SO THAT IF THE CLASS NAME CHANGES THEN
        // I WILL ONLY NEED TO CHANGE IT IN ONE PLACE IN THE CODE, i.e. next to the class keyword).
        return new self($value);
      };
      for ($i = 0; $i < $this->count - 1; $i++) {
         $output = array_map($func, $output);
      }
      return $output;
    }
    return null;
  }
}
$et = new EmbeddedTriplets(10, 3);
print_r($et->getEmbeddedOutput());

输出:

<br />
<b>Fatal error</b>:  Cannot access self:: when no class scope is active on line <b>25</b><br />

预期输出:

Array
(
    [0] => EmbeddedTriplets Object
        (
            [count:EmbeddedTriplets:private] => 1
            [values:EmbeddedTriplets:private] => Array
                (
                    [0] => EmbeddedTriplets Object
                        (
                            [count:EmbeddedTriplets:private] => 1
                            [values:EmbeddedTriplets:private] => Array
                                (
                                    [0] => 10
                                    [1] => 10
                                    [2] => 10
                                )
                        )
                    [1] => EmbeddedTriplets Object
                        (
                            [count:EmbeddedTriplets:private] => 1
                            [values:EmbeddedTriplets:private] => Array
                                (
                                    [0] => 10
                                    [1] => 10
                                    [2] => 10
                                )
                        )
                    [2] => EmbeddedTriplets Object
                        (
                            [count:EmbeddedTriplets:private] => 1
                            [values:EmbeddedTriplets:private] => Array
                                (
                                    [0] => 10
                                    [1] => 10
                                    [2] => 10
                                )
                        )
                )
        )
    [1] => EmbeddedTriplets Object
        (
            [count:EmbeddedTriplets:private] => 1
            [values:EmbeddedTriplets:private] => Array
                (
                    [0] => EmbeddedTriplets Object
                        (
                            [count:EmbeddedTriplets:private] => 1
                            [values:EmbeddedTriplets:private] => Array
                                (
                                    [0] => 10
                                    [1] => 10
                                    [2] => 10
                                )
                        )
                    [1] => EmbeddedTriplets Object
                        (
                            [count:EmbeddedTriplets:private] => 1
                            [values:EmbeddedTriplets:private] => Array
                                (
                                    [0] => 10
                                    [1] => 10
                                    [2] => 10
                                )
                        )
                    [2] => EmbeddedTriplets Object
                        (
                            [count:EmbeddedTriplets:private] => 1
                            [values:EmbeddedTriplets:private] => Array
                                (
                                    [0] => 10
                                    [1] => 10
                                    [2] => 10
                                )
                        )
                )
        )
    [2] => EmbeddedTriplets Object
        (
            [count:EmbeddedTriplets:private] => 1
            [values:EmbeddedTriplets:private] => Array
                (
                    [0] => EmbeddedTriplets Object
                        (
                            [count:EmbeddedTriplets:private] => 1
                            [values:EmbeddedTriplets:private] => Array
                                (
                                    [0] => 10
                                    [1] => 10
                                    [2] => 10
                                )
                        )
                    [1] => EmbeddedTriplets Object
                        (
                            [count:EmbeddedTriplets:private] => 1
                            [values:EmbeddedTriplets:private] => Array
                                (
                                    [0] => 10
                                    [1] => 10
                                    [2] => 10
                                )
                        )
                    [2] => EmbeddedTriplets Object
                        (
                            [count:EmbeddedTriplets:private] => 1
                            [values:EmbeddedTriplets:private] => Array
                                (
                                    [0] => 10
                                    [1] => 10
                                    [2] => 10
                                )
                        )
                )
        )
)

使用__CLASS__常量:

$class = __CLASS__;
return new $class($value);

从PHP 5.5.0开始,您可以使用class:

$class = self::class;

据我所知,仍然没有一条班轮。

这不是一个更好的解决方案(它实际上使用了更多的代码行),但它展示了如何将这些函数编码为使用类实例:

class EmbeddedTriplets {
  private $count;
  private $values;
  private $class;
  function __construct($value = 0, $count = 1) {
    $this->count = $count;
    $this->values = array($value, $value, $value);
    $this->class = __CLASS__;
  }
  public function getEmbeddedOutput() {
    if ($this->count > 0) {
      $output = $this->values;
      $class = $this->class;
      $func = function($value) use ($class) {
        return new $class($value);
      };
      for ($i = 0; $i < $this->count - 1; $i++) {
         $output = array_map($func, $output);
      }
      return $output;
    }
    return null;
  }
}
$et = new EmbeddedTriplets(10, 3);
print_r($et->getEmbeddedOutput());