coroutine php_PHP 多任务协程处理

本文首发于 PHP 多任务协程处理,转载请注明出处!上周 有幸和同事一起在 SilverStripe 分享最近的工作事宜。今天我计划分享 PHP 异步编程,不过由于上周我聊过 ReactPHP;我决定讨论一些不一样的内容。所以本文将探讨多任务协程这方面的内容。另外我还计划把这个主题加入到我正在筹备的一本 PHP 异步编程的图书中。虽然这本书相比本文来说会涉及更多细节,但我觉得本文依然具有实际意义!...
摘要由CSDN通过智能技术生成

本文首发于 PHP 多任务协程处理,转载请注明出处!

上周 有幸和同事一起在 SilverStripe 分享最近的工作事宜。今天我计划分享 PHP 异步编程,不过由于上周我聊过 ReactPHP;我决定讨论一些不一样的内容。所以本文将探讨多任务协程这方面的内容。

另外我还计划把这个主题加入到我正在筹备的一本 PHP 异步编程的图书中。虽然这本书相比本文来说会涉及更多细节,但我觉得本文依然具有实际意义!

那么,开始吧!

new MyIterator(

c0dad0b5552a351a4d74dbda699d51cc.png

这就是本文我们要讨论的问题。不过我们会从更简单更熟悉的示例开始。

一切从数组开始

我们可以通过简单的遍历来使用数组:

$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";

}

这是我们日常编码所依赖的基本实现。可以通过遍历数组获取每个元素的键名和键值。

当然,如果我们希望能够知道在何时可以使用数组。PHP 提供了一个方便的内置函数:

print is_array($array) ? "yes" : "no"; // yes

类数组处理

有时,我们需要对一些数据使用相同的方式进行遍历处理,但它们并非数组类型。比如对 DOMDocument 类进行处理:

$document = new DOMDocument();

$document->loadXML("

$elements = $document->getElementsByTagName("div");

print_r($elements); // DOMNodeList Object ( [length] => 1 )

这显然不是一个数组,但是它有一个 length 属性。我们能像遍历数组一样,对其进行遍历么?我们可以判断它是否实现了下面这个特殊的接口:

print ($elements instanceof Traversable) ? "yes" : "no"; // yes

这真的太有用了。它不会导致我们在遍历非可遍历数据时触发错误。我们仅需在处理前进行检测即可。

不过,这会引发另外一个问题:我们能否让自定义类也拥有这个功能呢?回答是肯定的!第一个实现方法类似如下:

class MyTraversable implements Traversable

{

// 在这里编码...

}

如果我们执行这个类,我们将看到一个错误信息:

PHP Fatal error: Class MyTraversable must implement interface Traversable as part of either Iterator or IteratorAggregate

Iterator(迭代器)

我们无法直接实现

class MyTraversable implements Iterator

{

// 在这里编码...

}

这个接口需要我们实现 5 个方法。让我们完善我们的迭代器:

class MyTraversable implements Iterator

{

protected $data;

protected $index = 0;

public function __construct($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);

}

}

这边我们需要注意几个事项:

我们需要存储构造器方法传入的 $data 数组,以便后续我们可以从中获取它的元素。

还需要一个内部索引(或指针)来跟踪 current 或 next 元素。

rewind() 仅仅重置 index 属性,这样 current() 和 next() 才能正常工作。

键名并非只能是数字类型!这里使用数组索引是为了保证示例足够简单。

我们可以向下面这样运行这段代码:

$iterator = new MyTraversable(["foo", "bar", "baz"]);

foreach ($iter

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值