简单讲述一下php里面的协程支持。
<?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 接口 /* //官方的代码 <?php 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!...