Created
August 21, 2018 15:06
-
-
Save predakanga/8159bd5ab9774dbbd7db151cb593feb6 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
{% for key, val in data %} | |
Key: {{ key }} | |
Value: {{ val ?: "0" }} | |
{% endfor %} |
This file contains hidden or 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 | |
require_once('vendor/autoload.php'); | |
$twig = new Twig_Environment(new Twig_Loader_Filesystem('.'), ['debug' => true]); | |
class LazyContext implements ArrayAccess, IteratorAggregate | |
{ | |
private $storage = []; | |
private $generator; | |
public function __construct(Generator $generator) | |
{ | |
$this->generator = $generator; | |
} | |
private function waitForMore() | |
{ | |
// NB: The try-finally construct is weird, but necessary for the fastest speeds! | |
// We want to yield before advancing the generator, to avoid waiting for the next item | |
// However, this means that if waitForMore is terminated early, it never advances | |
// This causes the last key to be emitted twice | |
// The sane but less-speedy way is to move the yield after the next, drop the try-finally | |
try { | |
// Foreach resets the generator on each call to waitForMore, so we'll iterate by hand | |
while ($this->generator->valid()) { | |
$key = $this->generator->key(); | |
$value = $this->generator->current(); | |
$this->storage[$key] = $value; | |
yield $key; | |
$this->generator->next(); | |
} | |
} finally { | |
if ($this->generator->valid()) { | |
$this->generator->next(); | |
} | |
} | |
} | |
public function offsetGet($offset) | |
{ | |
if (array_key_exists($offset, $this->storage)) { | |
return $this->storage[$offset]; | |
} | |
foreach ($this->waitForMore() as $key) { | |
if ($key === $offset) { | |
return $this->storage[$offset]; | |
} | |
} | |
throw new OutOfBoundsException("Key {$offset} is not set"); | |
} | |
public function offsetExists($offset) | |
{ | |
if (array_key_exists($offset, $this->storage)) { | |
return true; | |
} | |
foreach ($this->waitForMore() as $key) { | |
if ($key === $offset) { | |
return true; | |
} | |
} | |
return false; | |
} | |
public function offsetSet($offset, $value) | |
{ | |
throw new LogicException('Context is read-only'); | |
} | |
public function offsetUnset($offset) | |
{ | |
throw new LogicException('Context is read-only'); | |
} | |
public function getIterator() | |
{ | |
foreach ($this->storage as $key => $value) { | |
yield $key => $value; | |
} | |
foreach ($this->waitForMore() as $key) { | |
yield $key => $this->storage[$key]; | |
} | |
} | |
} | |
function controllerFunc() | |
{ | |
yield 'template' => 'index.twig'; | |
foreach (range('a', 'z') as $key) { | |
$shouldWait = (bool)random_int(0, 1); | |
if ($shouldWait) { | |
sleep(random_int(1, 3)); | |
} | |
yield $key => $shouldWait; | |
} | |
} | |
$ctx = new LazyContext(controllerFunc()); | |
echo "Template is: {$ctx['template']}\n"; | |
$twig->display($ctx['template'], ['data' => $ctx]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment