我试图在 CLI 程序中创建一个类似“池”的结构,其中包括许多“借用”和“回收”。在测试的时候,我遇到了一些非常出乎意料的事情:
<?php
class FOO
{
public static $pool=[];
public static function get()
{
if(empty(self::$pool))
{
self::$pool[]=new self(mt_rand(1000,9999));
}
return array_shift(self::$pool);
}
protected static function recycle(FOO $foo)
{
echo "Recycling {$foo->num}\n";
self::$pool[]=$foo;
}
public $num;
protected function __construct(int $num)
{
$this->num=$num;
}
public function __destruct()
{
static::recycle($this);
}
}
function Bar()
{
$foo=FOO::get();
echo "Got {$foo->num}\n";
}
echo "Bar\n";
Bar();
echo "Bar\n";
Bar();
echo "Bar\n";
Bar();
echo "Bar\n";
Bar();
print_r(FOO::$pool);
echo "End.\n";
输出是:
Bar
Got 2911
Recycling 2911
Bar
Got 2911
Bar
Got 1038
Recycling 1038
Bar
Got 1038
Array
(
)
End.
如果我将Bar()调用限制为 3 次而不是 4 次,我会得到以下输出:
Bar
Got 7278
Recycling 7278
Bar
Got 7278
Bar
Got 6703
Recycling 6703
Array
(
[0] => FOO Object
(
[num] => 6703
)
)
End.
在这里你可以看到,当一个对象被“重用”时(见例1中的2911和1038,例2中的7278),它__destruct()不会被调用;相反,它会简单地消失。
我很困惑。为什么会发生这种情况?为什么FOO->__destruct每次都不叫?是否可以制作FOO自动回收实例?
我在 PHP-7.2 中对此进行了测试,在 Windows 和 WSL-Ubuntu 中都观察到了这种行为。
子衿沉夜