简单讲述一下php里面的协程支持。
//yield是干什么的?
//当程序运行到yield的时候,当前程序就唤起协程记录上下文。
function num()
{
for ($i=1;$i<10;$i++)
{
yield $i;
}
}
foreach(num() as $n){
echo $n."\n";
}
//当然还可以这样
function printer() {
while (true) {
$string = yield;
echo $string;
}
}
$printer = printer();
$printer->send("Hello world! \n");
//Generator 是干什么的,Generator 是迭代器,实现了Iterator 接口
/*
//官方的代码
class Generator implements Iterator {
public function rewind(); // Rewinds the iterator. If
// iteration has already begun,
// this will throw an exception.
public function valid(); // Returns false if the
// iterator has been closed.
// Otherwise returns true.
public function current(); // Returns the yielded value.
public function key(); // Returns the yielded key.
public function next(); // Resumes execution of the
// generator.
public function send($value); // Sends the given value to the
// generator as the result of
// the yield expression and
// resumes execution of the
// generator.
}
?>
*/
//利用Generator写一个中间件,类似于laravel框架的中间件
function MyMiddleware($middleware = [])
{
$stack = [];
foreach ($middleware as $mid)
{
$handle = call_user_func_array($mid,[]);
$stack[] = $handle;
$handle->current();
}
while($handle = array_pop($stack)){
$handle->send("ok! \n");
$handle->next();
}
}
function one(){
echo "this is one start \n";
$a = yield;
echo $a;
echo "this is one end \n";
}
function two(){
echo "this is two start \n";
$a = yield;
echo $a;
echo "this is two end \n";
}
MyMiddleware(['one','two']);
//再列举一个生产 和 消费者直接的例子 加以说明
function consumer()
{
while (true)
{
$n = yield;
if(!$n){
return;
}
echo '[CONSUMER] Consuming'.$n.'...'."\n";
sleep(1);
$msg = '200,ok!';
yield $msg;
}
}
function produce(Generator $generator)
{
$n = 0;
while ($n < 5)
{
$n ++;
echo '[PRODUCER] Producing '.$n.'...'."\n";
$generator->send($n);
$msg = $generator->current();
$generator->next();
echo '[PRODUCER] Consumer return: '.$msg.'...'."\n";
}
}
$c = consumer();
produce($c);
/**
* 解释
* 启动生成器
* 然后,一旦生产了东西,通过$generator.send($n)切换到consumer执行
* consumer通过yield拿到消息,处理,又通过yield把结果传回
* produce拿到consumer处理的结果,继续生产下一条消息
* 直到produce结束
*/
以上代码可以直接拷贝到本地使用php 命令运行。
输出结果:
D:\myapache\www\demo\middleware>php demo.php 1 2 3 4 5 6 7 8 9 Hello world! this is one start this is two start ok! this is two end ok! this is one end [PRODUCER] Producing 1... [CONSUMER] Consuming1... [PRODUCER] Consumer return: 200,ok!... [PRODUCER] Producing 2... [CONSUMER] Consuming2... [PRODUCER] Consumer return: 200,ok!... [PRODUCER] Producing 3... [CONSUMER] Consuming3... [PRODUCER] Consumer return: 200,ok!... [PRODUCER] Producing 4... [CONSUMER] Consuming4... [PRODUCER] Consumer return: 200,ok!... [PRODUCER] Producing 5... [CONSUMER] Consuming5... [PRODUCER] Consumer return: 200,ok!...