src/Phan/Library/RAII.php
<?php
declare(strict_types=1);
namespace Phan\Library;
use Closure;
/**
* Implements Resource Acquisition Is Initialization.
* A defined but unused variable in a function/method scope can be used to create this,
* and the passed in finalizer closure will be called when that function/method returns.
*
* Note: This assumes that the garbage collector eagerly calls __destruct.
* This may not be the case in alternate PHP implementations.
*
* @see https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization
*/
class RAII
{
/** @var null|Closure():void this is called exactly once, either during __destruct (when the variable goes out of scope) or manually */
private $finalizer;
/**
* @param Closure():void $finalizer - Should not throw an exception. It may be called in __destruct()
*/
public function __construct(Closure $finalizer)
{
$this->finalizer = $finalizer;
}
/**
* Calls the finalizer, unless it has already been called.
*/
public function callFinalizerOnce(): void
{
if ($this->finalizer) {
($this->finalizer)();
$this->finalizer = null;
}
}
public function __destruct()
{
$this->callFinalizerOnce();
}
}