#dpc #Amsterdam
Писатель и кодер, работающий в SilverStripe.
Кристофер - писатель и кодер, работающий в SilverStripe. Обычно он работает над архитектурой приложений, хотя иногда вы найдете его компиляторами или роботами.
$array = ["foo", "bar", "baz"];
foreach ($array as $key => $value) {
print "item: " . $key . "|" . $value . "\n";
}
for ($i = 0; $i < count($array); $i++) {
print "item: " . $i . "|" . $array[$i] . "\n";
}print is_array($array) ? "yes" : "no"; // yes$document = new DOMDocument();
$document->loadXML("<div></div>");
$elements = $document->getElementsByTagName("div");
print_r($elements); // DOMNodeList Object ( [length] => 1 )print ($elements instanceof Traversable) ? "yes" : "no"; // yesclass MyTraversable implements Traversable
{
// тут пишем код...
}PHP Fatal error: Class MyTraversable must implement interface Traversable as part of either Iterator or IteratorAggregate…
Попробуем...
class MyIterator implements Iterator
{
// пишем код тутclass MyIterator implements Iterator
{
protected $data;
protected $index = 0;
public function __construct(array $data)
{
$this->data = $data;
}
public function current()
{
return $this->data[$this->index];
}
public function next()
{
return $this->data[$this->index++];
}
public function key()
{
return $this->index;
}
public function rewind()
{
$this->index = 0;
}
public function valid()
{
return $this->index < count($this->data);
}
}Последовательность методов в foreach цикле:
$iterator = new MyIterator(["foo", "bar", "baz"]);
foreach ($iterator as $key => $value) {
print "item: " . $key . "|" . $value . "\n";
}class MyIteratorAggregate implements IteratorAggregate
{
protected $data;
public function __construct(array $data)
{
$this->data = $data;
}
public function getIterator()
{
return new ArrayIterator($this->data);
}
}$content = file_get_contents(__FILE__);
$lines = explode("\n", $content);
foreach ($lines as $i => $line) {
print $i . ". " . $line . "\n";
}function lines($file) {
$handle = fopen($file, "r");
while (!feof($handle)) {
yield trim(fgets($handle));
}
fclose($handle);
}
foreach (lines(__FILE__) as $i => $line) {
print $i . ". " . $line . "\n";
}print_r(lines(__FILE__)); // Generator Object ( )print_r(get_class_methods(lines(__FILE__)));
// Array
// (
// [0] => rewind
// [1] => valid
// [2] => current
// [3] => key
// [4] => next
// [5] => send
// [6] => throw
// [7] => __wakeup
// )$generator = call_user_func(function() {
yield "foo";
});
print $generator->current() . "\n"; // foo$generator = call_user_func(function() {
$input = (yield "foo");
print "inside: " . $input . "\n";
});
print $generator->current() . "\n";
$generator->send("bar");$multiply = function ($x, $y) {
yield $x * $y;
};
print $multiply(5, 6)->current(); // 30$calculate = function ($op, $x, $y) use ($multiply) {
if ($op === "multiply") {
$generator = $multiply($x, $y);
return $generator->current();
}
};
print $calculate("multiply", 5, 6); // 30$calculate = function ($op, $x, $y) use ($multiply) {
if ($op === "multiply") {
$generator = $multiply($x, $y);
if (!is_numeric($x) || !is_numeric($y)) {
throw new InvalidArgumentException();
}
return $generator->current();
}
};
print $calculate("multiply", 5, "foo"); // PHP Fatal error...$multiply = function ($x, $y) {
try {
yield $x * $y;
} catch (InvalidArgumentException $exception) {
print "ERRORS!";
}
};
$calculate = function ($op, $x, $y) use ($multiply) {
if ($op === "multiply") {
$generator = $multiply($x, $y);
if (!is_numeric($x) || !is_numeric($y)) {
$generator->throw(new InvalidArgumentException());
}
return $generator->current();
}
};Coroutines - это программные компоненты, которые обобщают подпрограммы для неперехваченной многозадачности, позволяя нескольким точкам входа приостанавливать и возобновлять выполнение в определенных местах
Согласованная многозадачность, также известная как неперехваченная многозадачность, представляет собой стиль многозадачности, в котором операционная система никогда не инициирует переключение контекста из работающего процесса в другой процесс. Вместо этого процессы добровольно дают управление периодически или в режиме ожидания, чтобы одновременно запускать несколько приложений.
class Task
{
protected $generator;
public function __construct(Generator $generator)
{
$this->generator = $generator;
}
public function run()
{
$this->generator->next();
}
public function finished()
{
return !$this->generator->valid();
}
}Нам нужна задача
class Scheduler
{
protected $queue;
public function __construct()
{
$this->queue = new SplQueue();
}
public function enqueue(Task $task)
{
$this->queue->enqueue($task);
}
public function run()
{
while (!$this->queue->isEmpty()) {
$task = $this->queue->dequeue();
$task->run();
if (!$task->finished()) {
$this->enqueue($task);
}
}
}
}$scheduler = new Scheduler();
$task1 = new Task(call_user_func(function() {
for ($i = 0; $i < 3; $i++) {
print "task 1: " . $i . "\n";
yield;
}
}));
$task2 = new Task(call_user_func(function() {
for ($i = 0; $i < 6; $i++) {
print "task 2: " . $i . "\n";
yield;
}
}));
$scheduler->enqueue($task1);
$scheduler->enqueue($task2);
$scheduler->run();task 1: 0
task 1: 1
task 2: 0
task 2: 1
task 1: 2
task 2: 2
task 2: 3
task 2: 4
task 2: 5class Task
{
protected $generator;
protected $run = false;
public function __construct(Generator $generator)
{
$this->generator = $generator;
}
public function run()
{
if ($this->run) {
$this->generator->next();
} else {
$this->generator->current();
}
$this->run = true;
}
public function finished()
{
return !$this->generator->valid();
}
}Привет!