lea*_*php 13 php closures bind
php文档中的示例Closure::bind包含static匿名函数声明.为什么?如果删除它,我找不到区别.
用:
class A { private static $sfoo = 1; }
$cl1 = static function() { return self::$sfoo; }; // notice the "static"
$bcl1 = Closure::bind($cl1, null, 'A');
echo $bcl1(); // output: 1
Run Code Online (Sandbox Code Playgroud)
没有:
class A { private static $sfoo = 1; }
$cl1 = function() { return self::$sfoo; };
$bcl1 = Closure::bind($cl1, null, 'A');
echo $bcl1(); // output: 1
Run Code Online (Sandbox Code Playgroud)
lea*_*php 24
发现了区别:你不能将静态闭包绑定到对象,只能更改对象范围.
class foo { }
$cl = static function() { };
Closure::bind($cl, new foo); // PHP Warning: Cannot bind an instance to a static closure
Closure::bind($cl, null, 'foo') // you can change the closure scope
Run Code Online (Sandbox Code Playgroud)
jlh*_*jlh 13
我不敢苟同。确实,这通常无关紧要。但有时它的问题一大堆。
持有对 的引用的闭包$this可能会阻止对该对象的垃圾收集,这反过来也可能显着影响性能。这是一个真正产生巨大差异的例子:
class LargeObject {
protected $array;
public function __construct() {
$this->array = array_fill(0, 2000, 17);
}
public function getItemProcessor(): Closure {
// Try with and without 'static' here
return static function () {
// do some processing unrelated to $this
};
}
}
$start = microtime(true);
$processors = [];
for ($i = 0; $i < 2000; $i++) {
$lo = new LargeObject();
$processors[] = $lo->getItemProcessor();
}
$memory = memory_get_usage() >> 20;
$time = (microtime(true) - $start) * 1000;
printf("This took %dms and %dMB of memory\n", $time, $memory);
Run Code Online (Sandbox Code Playgroud)
这是正常关闭的输出:
This took 55ms and 134MB of memory
Run Code Online (Sandbox Code Playgroud)
这是带有静态闭包的输出:
This took 22ms and 1MB of memory
Run Code Online (Sandbox Code Playgroud)
我在 Debian Buster 上用 PHP 7.3.19 对此进行了测试,所以 YMMV。显然,这是一个专门构造的示例来演示差异。但是这样的事情也可能发生在实际应用中。我开始使用 Slevomat 的SlevomatCodingStandard.Functions.StaticClosure嗅探来提醒我总是使用静态闭包。
小智 11
与其他静态方法一样,静态闭包也无法访问$this。
像任何其他方法一样,不访问的非静态闭包$this通常将在静态上下文中工作。
但是,静态闭包与任何其他静态方法一样,在性能上比非静态闭包略有好处,因此,出于微代码优化的考虑,我个人建议声明任何不需要访问$this为静态的闭包。
正如您所注意到的,这并不重要,尽管如果您将E_STRICT包括在内,它可能会显示为错误error_reporting。(更新:不,不是)
就像static在类方法上使用关键字一样。如果您未在方法中进行引用,则不一定需要它$this(尽管这确实违反了严格的标准)。
我想PHP可以解决您的问题Closure,A因为null第二个参数是静态访问bind()
| 归档时间: |
|
| 查看次数: |
6442 次 |
| 最近记录: |