つい先日、私の電報チャンネルの 1 つの投稿に関して、ある購読者から質問がありました。彼はこのコードの断片に戸惑いました。
<?php
usort($firstArray, static function($first, $second) {
return $first <=> $second;
});
質問は次のように聞こえました。
なぜ usort コールバックを静的にするのですか?
そして、これは注意を払うべき非常に良い質問だと思いました。
何が問題ですか?
同期するドキュメントの定義から始めましょう:
クロージャーとも呼ばれる匿名関数を使用すると、特定の名前を持たない関数を作成できます。これらは呼び出し可能なパラメータ値として最も有用です が、他の多くの用途もあります。
匿名関数はClosureクラスを使用して実装され ます。
そこに、しかしほとんど誰もこれを読んでいません:
クラスのコンテキストで宣言すると、現在のクラスが自動的にそれに関連付けられ、クラスの関数内で $ this を使用できるようになります。現在のクラスに自動的にリンクしたくない場合は、静的匿名関数を使用します。
, losure , . , $this
:
,
<?php
class ExampleTest extends TestCase
{
public function testBasicTest(): void
{
$array = [2, 1];
usort($array, function ($first, $second) {
var_dump($this);
return $first <=> $second;
});
self::assertTrue(true);
}
}
" ", .
, $this, , , , .
static:
<?php
class LargeObject {
protected $array;
public function __construct() {
$this->array = array_fill(0, 2000, 15);
}
public function getItemProcessor(): Closure {
return function () { //
$a = 1;
$b = 2;
return $a + $b;
};
}
}
function getPeakMemory(): string
{
return sprintf('%.2F MiB', memory_get_peak_usage() / 1024 / 1024);
}
$start = microtime(true);
$processors = [];
for ($i = 0; $i < 2000; $i++) {
$lo = new LargeObject();
$processors[] = $lo->getItemProcessor();
}
var_dump(getPeakMemory());
, string(10) "134.10 MiB"
, static 11 , string(8) "1.19 MiB"
, processors[]
, losures , , , .
, static . static, , .
P.S.
. - https://t.me/beerphp. .