类方法中的 PHP 匿名函数隐藏类名(想使用 self 之类的东西来处理类名)
Posted
技术标签:
【中文标题】类方法中的 PHP 匿名函数隐藏类名(想使用 self 之类的东西来处理类名)【英文标题】:PHP anonymous function within class method hides class name (would like to use something like self to address the class name) 【发布时间】:2015-04-17 13:26:15 【问题描述】:在下面的 php 代码中,一行代码已被注释掉(参见 cmets)并替换为下一行,目的是在不指定类名的情况下达到相同的效果。但是,我试图在我的代码中消除的显式类名对函数是隐藏的。如何在不像原始代码那样明确写下类名的情况下解决这个问题?
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;
据我所知,仍然没有单行。
【讨论】:
单线也可以做同样的事情吗?return new __CLASS__($value);
不起作用。有没有别的解决办法。如果可能的话,我不想创建那个额外的变量。谢谢。
我很确定没有,但也许其他人有想法。
让我们拭目以待。如果没有人提出任何建议,那么我会接受您的回答(如果 PHP 实现了一个等效于 call_user_func()
的名称为 new_instance()
或其他东西,那就太好了。谢谢。
似乎是一个语法问题(PHP 语法不允许我们想使用它的常量)。
不,因为一旦你在闭包中,你就超出了类范围(不再在类中)。 php 文件中的所有函数基本上都被“拉”到顶层。您必须将类存储在一个变量中并将其传入。另请注意,__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());
【讨论】:
以上是关于类方法中的 PHP 匿名函数隐藏类名(想使用 self 之类的东西来处理类名)的主要内容,如果未能解决你的问题,请参考以下文章