Skip to content

Instantly share code, notes, and snippets.

@jm42
Created August 21, 2014 02:17
Show Gist options
  • Save jm42/29cb0c9be5f6005d1628 to your computer and use it in GitHub Desktop.
Save jm42/29cb0c9be5f6005d1628 to your computer and use it in GitHub Desktop.
Simulating using/with in PHP
<?php
class Singleton // https://github.com/Trismegiste/Php-Is-Magic
{
public static function getInstance()
{
static $instances = array();
$key = get_called_class();
if (!array_key_exists($key, $instances)) {
$instances[$key] = new $key();
}
return $instances[$key];
}
private function __construct() {}
private function __clone() {}
public function __wakeup() {}
}
###############################################################################
abstract class State extends Singleton {
private $stack = array();
public function push($value) {
if (count($this->stack) === 0) {
$this->stack[] = $value;
} else {
$top = $this->top();
if (!$this->supports($top)) {
throw new \LogicException();
}
$data = $this->get($top, $value);
$this->stack[] = $data;
}
}
public function pop() {
array_pop($this->stack);
}
public function top() {
$num = count($this->stack) - 1;
$top = $this->stack[$num];
return $top;
}
abstract public function supports($value);
abstract public function get($parent, $value);
}
class ObjectState extends State {
public function supports($value) {
return is_object($value);
}
public function get($parent, $value) {
return $parent->$value;
}
}
###############################################################################
function using(&$variable) {
$state = ObjectState::getInstance();
$state->push($variable);
yield this();
$state->pop();
}
function with($property) {
$state = ObjectState::getInstance();
$state->push($property);
yield this();
$state->pop();
}
function this() {
return ObjectState::getInstance()->top();
}
###############################################################################
class PersonLikes extends \ArrayObject {};
class Person {
public $name;
public $likes;
public function __construct($name, array $likes = array()) {
$this->name = $name;
$this->likes = new PersonLikes($likes);
}
}
$person = new Person('John', ['Rugby', 'Bananas']);
###############################################################################
foreach (using($person) as $_) {
echo this()->name;
echo ' likes ';
foreach (with('likes') as $_) {
$_[] = 'PHP'; // Add PHP to likes
echo implode(', ', (array) this());
}
echo '.';
echo PHP_EOL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment