3v4l.org

run code in 300+ PHP versions simultaneously
<?php namespace fiberEnabled { /** @return iterable<int> */ function fibonacciSequence(): iterable { $a = 0; $b = 1; while (true) { yield $a; // Imagine if this had to yield a Promise: // All callers would also have to return a promise and know how to wait for it to resolve if (\Fiber::getCurrent()) { \Fiber::suspend(); } $c = $a; $a = $b; $b += $c; } } function fetch5th(): int { foreach (fibonacciSequence() as $key => $i) { if ($key === 19) { return $i; } } } function fetchFirstTen(): array { $result = []; foreach (fibonacciSequence() as $key => $i) { $result[] = $i; if ($key === 9) { return $result; } } } function file_get_contents(string $file): string { if (!\Fiber::getCurrent()) { return \file_get_contents($file); } $stream = fopen($file, 'r'); \stream_set_blocking($stream, false); \stream_set_read_buffer($stream, 0); $data = ''; while (!\feof($stream)) { \Fiber::suspend(); $partial = \stream_get_contents($stream, length: 4); // Simulate read latency var_dump($partial); $data .= $partial; } \fclose($stream); return $data; } // NOTE: A real fiber event loop would be able to pool these and 'await' them alternatingly. // If it was waiting for a network request they may return in a different order. // Fibers can repeatedly suspend and let other fibers continue while waiting for an external condition. function fiberAll(array $fibers): array { foreach ($fibers as $key => $fiber) { if (!$fiber->isStarted()) { $fiber->start(); } while ($fiber->isSuspended()) { echo 'Fiber suspended, resuming...', "\n"; $fiber->resume(); } } return $fibers; } } namespace { file_put_contents('/tmp/test123', 'Some test text data'); // Whether used directly, outside of an event loop... print_r(\fiberEnabled\fetch5th()); echo "\n"; print_r(\fiberEnabled\fetchFirstTen()); print_r(\fiberEnabled\file_get_contents('/tmp/test123')); echo "\n"; // Or used as part of an event loop... $fibers = \fiberEnabled\fiberAll([ 'fetch5th' => new Fiber(\fiberEnabled\fetch5th(...)), 'fetchFirstTen' => new Fiber(\fiberEnabled\fetchFirstTen(...)), 'fileContent' => new Fiber(fn () => \fiberEnabled\file_get_contents('/tmp/test123')), ]); print_r($fibers['fetch5th']->getReturn()); echo "\n"; print_r($fibers['fetchFirstTen']->getReturn()); print_r($fibers['fileContent']->getReturn()); echo "\n"; }
Output for 8.1.32, 8.2.0 - 8.2.29, 8.3.0 - 8.3.26, 8.4.1 - 8.4.13
4181 Array ( [0] => 0 [1] => 1 [2] => 1 [3] => 2 [4] => 3 [5] => 5 [6] => 8 [7] => 13 [8] => 21 [9] => 34 ) Some test text data Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... Fiber suspended, resuming... string(4) "Some" Fiber suspended, resuming... string(4) " tes" Fiber suspended, resuming... string(4) "t te" Fiber suspended, resuming... string(4) "xt d" Fiber suspended, resuming... string(3) "ata" 4181 Array ( [0] => 0 [1] => 1 [2] => 1 [3] => 2 [4] => 3 [5] => 5 [6] => 8 [7] => 13 [8] => 21 [9] => 34 ) Some test text data

preferences:
73.59 ms | 410 KiB | 5 Q