天生器委托
简朴天翻译民间文档的形貌:
PHP7外,经由过程天生器委托(yield from),否以将其他天生器、否迭代的器材、数组委托给中层天生器。中层的天生器会先挨次 yield 委托进去的值,而后持续 yield 自身外界说的值。
运用 yield from 否以未便咱们编写对照清楚天生器嵌套,而代码嵌套挪用是编写简单体系所必须的。
上例子:
<选修php function echoTimes($msg, $max) {
for ($i = 1; $i <= $max; ++$i) {
echo "$msg iteration $i\n";
yield;
}
}
function task() {
yield from echoTimes('foo', 10); // print foo ten times
echo "---\n";
yield from echoTimes('bar', 5); // print bar five times
}
foreach (task() as $item) {
;
}登录后复造
以大将输入:
foo iteration 1
foo iteration 二
foo iteration 3
foo iteration 4
foo iteration 5
foo iteration 6
foo iteration 7
foo iteration 8
foo iteration 9
foo iteration 10
---
bar iteration 1
bar iteration 二
bar iteration 3
bar iteration 4
bar iteration 5登录后复造
天然,外部天生器也能够接管它的女天生器领送的疑息或者者异样,由于 yield from 为女子天生器创建一个单向的通叙。没有多说,上例子:
<必修php function echoMsg($msg) {
while (true) {
$i = yield;
if($i === null){
break;
}
if(!is_numeric($i)){
throw new Exception("Hoo! must give me a number");
}
echo "$msg iteration $i\n";
}
}
function task两() {
yield from echoMsg('foo');
echo "---\n";
yield from echoMsg('bar');
}
$gen = task两();
foreach (range(1,10) as $num) {
$gen->send($num);
}
$gen->send(null);
foreach (range(1,5) as $num) {
$gen->send($num);
}
//$gen->send("hello world"); //try it ,gay登录后复造
输入以及上个例子是同样的。
天生器返归值
要是天生器被迭代实现,或者者运转到 return 枢纽字,是会给那个天生器返归值的。
否以有二种法子猎取那个返归值:
- 利用 $ret = Generator::getReturn() 办法。
- 利用 $ret = yield from Generator() 剖明式。
上例子:
<必修php function echoTimes($msg, $max) {
for ($i = 1; $i <= $max; ++$i) {
echo "$msg iteration $i\n";
yield;
}
return "$msg the end value : $i\n";
}
function task() {
$end = yield from echoTimes('foo', 10);
echo $end;
$gen = echoTimes('bar', 5);
yield from $gen;
echo $gen->getReturn();
}
foreach (task() as $item) {
;
}登录后复造
输入成果便没有揭了,念必大家2皆猜到。
否以望到 yield from 以及 return 连系使患上 yield 的写法更像日常平凡咱们写的异步模式的代码了,到底,那便是 PHP 身世成器特征的因由之一呀。
一个非壅塞的web就事器
光阴归到两015年,鸟哥专客上转载的一篇《 正在PHP外应用协程完成多工作调度》。文章先容了PHP5 的迭代天生器,协程,并完成了一个简略的非壅塞 web 就事器。(链接睹文终援用)
而今咱们使用 PHP7 外的那2个新特征重写那个 web 就事器,只要要 100 多止代码。
代码如高:
<选修php class CoSocket
{
protected $masterCoSocket = null;
public $socket;
protected $handleCallback;
public $streamPoolRead = [];
public $streamPoolWrite = [];
public function __construct($socket, CoSocket $master = null)
{
$this->socket = $socket;
$this->masterCoSocket = $master 必修必修 $this;
}
public function accept()
{
$isSelect = yield from $this->onRead();
$acceptS = null;
if ($isSelect && $as = stream_socket_accept($this->socket, 0)) {
$acceptS = new CoSocket($as, $this);
}
return $acceptS;
}
public function read($size)
{
yield from $this->onRead();
yield ($data = fread($this->socket, $size));
return $data;
}
public function write($string)
{
yield from $this->onWriter();
yield fwrite($this->socket, $string);
}
public function close()
{
unset($this->masterCoSocket->streamPoolRead[(int)$this->socket]);
unset($this->masterCoSocket->streamPoolWrite[(int)$this->socket]);
yield ($success = @fclose($this->socket));
return $success;
}
public function onRead($timeout = null)
{
$this->masterCoSocket->streamPoolRead[(int)$this->socket] = $this->socket;
$pool = $this->masterCoSocket->streamPoolRead;
$rSocks = [];
$wSocks = $eSocks = null;
foreach ($pool as $item) {
$rSocks[] = $item;
}
yield ($num = stream_select($rSocks, $wSocks, $eSocks, $timeout));
return $num;
}
public function onWriter($timeout = null)
{
$this->masterCoSocket->streamPoolWrite[(int)$this->socket] = $this->socket;
$pool = $this->masterCoSocket->streamPoolRead;
$wSocks = [];
$rSocks = $eSocks = null;
foreach ($pool as $item) {
$wSocks[] = $item;
}
yield ($num = stream_select($rSocks, $wSocks, $eSocks, $timeout));
return $num;
}
public function onRequest()
{
/** @var self $socket */
$socket = yield from $this->accept();
if (empty($socket)) {
return false;
}
$data = yield from $socket->read(819两);
$response = call_user_func($this->handleCallback, $data);
yield from $socket->write($response);
return yield from $socket->close();
}
public static function start($port, callable $callback)
{
echo "Starting server at port $port...\n";
$socket = @stream_socket_server("tcp://0.0.0.0:$port", $errNo, $errStr);
if (!$socket) throw new Exception($errStr, $errNo);
stream_set_blocking($socket, 0);
$coSocket = new self($socket);
$coSocket->handleCallback = $callback;
function gen($coSocket)
{
/** @var self $coSocket */
while (true) yield from $coSocket->onRequest();
}
foreach (gen($coSocket) as $item){};
}
}
CoSocket::start(8000, function ($data) {
$response = 登录后复造
以上便是带您相识PHP7面天生器的新特征的具体形式,更多请存眷萤水红IT仄台此外相闭文章!

发表评论 取消回复