Created
August 21, 2014 02:17
-
-
Save jm42/29cb0c9be5f6005d1628 to your computer and use it in GitHub Desktop.
Simulating using/with in PHP
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 | |
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