oop — анонимная функция PHP внутри метода класса скрывает имя класса (хотелось бы использовать что-то вроде self для адресации имени класса)

В коде 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
)

)

)

)

)

1

Решение

Использовать __CLASS__ постоянная:

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

Начиная с PHP 5.5.0 вы можете использовать class:

$class = self::class;

Насколько я знаю, до сих пор нет единой строки.

2

Другие решения

Не намного лучшее решение (на самом деле оно использует больше строк кода), но оно показывает, как такие функции также можно кодировать для использования экземпляров классов:

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

По вопросам рекламы [email protected]