Skip to content

Instantly share code, notes, and snippets.

@m3g4p0p
Last active August 19, 2016 07:37
Show Gist options
  • Save m3g4p0p/d4d8dd3b1b9cbe42564c3f603eafe8fc to your computer and use it in GitHub Desktop.
Save m3g4p0p/d4d8dd3b1b9cbe42564c3f603eafe8fc to your computer and use it in GitHub Desktop.
Store and restore the states of objects
<?php
/**
* Optional convenience class. Objects extending the
* StateHandler class can register with a StateArchivist
* instance; then calling remember() or restore() on the
* archivist will be propagated to all registered objects.
*/
class StateArchivist {
/**
* The array of objects
* @var array
*/
private $objects = [];
/**
* Register an object that extends the StateHandler
* class and initially have it remember its state
* (unless specified otherwise).
* @param StateHandler $object
* @param boolean $remember
*/
public function register(
StateHandler $object,
$remember = true
) {
if ($remember) {
$object->remember();
}
$this->objects[] = $object;
}
/**
* Call the remember() function on
* all registered objects
*/
public function remember() {
foreach ($this->objects as $object) {
$object->remember();
}
}
/**
* Call the restore function on all objects
*/
public function restore() {
foreach ($this->objects as $object) {
$object->restore();
}
}
}
?>
<?php
/**
* Objects extending this class can remember
* and later restore their state
*/
class StateHandler {
/**
* The array of states
* @var array
*/
private $states = [];
/**
* Optionally takes an instance of a StateArchivist
* as parameter where it immediately registers itself
* @param StateArchivist|null $archivist
*/
public function __construct(StateArchivist $archivist = null) {
if ($archivist) {
$archivist->register($this);
}
}
/**
* Store the current state
*/
public function remember() {
$state = get_object_vars($this);
unset($state['states']);
$this->states[] = $state;
}
/**
* Restore the last state
*/
public function restore() {
$state = array_pop($this->states);
if (!$state) return;
foreach ($state as $key => $value) {
$this->$key = $value;
}
}
}
?>
@m3g4p0p
Copy link
Author

m3g4p0p commented Aug 15, 2016

Sample usage:

<?php
class Counter extends StateHandler {
  public $count = 0;

  public function increment() {
    return ++$this->count;
  }
}

$archivist = new StateArchivist();
$counter = new Counter($archivist);

echo $counter->increment() . PHP_EOL; // 1
$archivist->remember();
echo $counter->increment() . PHP_EOL; // 2
$archivist->restore();
echo $counter->count . PHP_EOL;       // 1
$archivist->restore();
echo $counter->count . PHP_EOL;       // 0
?>

License

MIT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment