Created
October 12, 2022 14:13
-
-
Save inxilpro/014b093d08472fc70c422203d9c722f4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$a = 'foo'; | |
dump($a); // "foo" | |
snapshot($a); | |
$a = 'bar'; | |
dump($a); // "bar" | |
restore($a); | |
dump($a); // "foo" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function snapshot(&$variable) | |
{ | |
return Snapshots::instance()->snapshot($variable); | |
} | |
function restore(&$variable) { | |
return Snapshots::instance()->restore($variable); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Support\Collection; | |
class Snapshots | |
{ | |
protected static ?self $instance = null; | |
public static function instance(): self | |
{ | |
return static::$instance ??= new self(); | |
} | |
public function __construct( | |
public Collection $cache = new Collection() | |
) { | |
} | |
public function &snapshot(&$variable) | |
{ | |
$snapshot = $variable; | |
$this->cache[] = function(&$restoring) use (&$variable, $snapshot) { | |
if ($this->match($variable, $restoring)) { | |
$variable = $snapshot; | |
return true; | |
} | |
return false; | |
}; | |
return $variable; | |
} | |
public function &restore(&$variable) | |
{ | |
$this->cache = $this->cache->reject(function($matcher) use (&$variable) { | |
return $matcher($variable); | |
}); | |
return $variable; | |
} | |
protected function match(&$a, &$b): bool | |
{ | |
if ($a !== $b) { | |
return false; | |
} | |
return match(true) { | |
is_object($a) => true, | |
is_scalar($a) && $this->areLinked($a, $b) => true, | |
is_array($a) && $this->areLinked($a, $b) => true, | |
default => false, | |
}; | |
} | |
protected function areLinked(&$a, &$b): bool | |
{ | |
$backup = $a; | |
try { | |
$a = new stdClass(); | |
return $b === $a; | |
} finally { | |
$a = $backup; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment