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

时间:2015-02-16 22:30:11

标签: php oop methods functional-programming classname

在下面的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
                                )

                        )

                )

        )

)

2 个答案:

答案 0 :(得分:2)

使用__CLASS__常量:

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

从PHP 5.5.0起,您可以使用class

$class = self::class;

据我所知,仍然没有任何一个班轮。

答案 1 :(得分:0)

没有更好的解决方案(它实际上使用了更多的代码行),但它显示了如何编码这些函数以使用类实例:

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