首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

更新后的 PHP PHP 的新面孔(4)

更新后的 PHP PHP 的新面孔(4)

生成器 在发布 PHP 5.0 的之后,人们开始使用标准 PHP 库 (SPL)。SPL                是解决某些计算机科学问题的一组标准方法,比如创建队列和链表(并提供可扩展的特性,比如类文件自动加载机)。
SPL 中包含一个叫做 iterator 的特性。Iterator                是一个接口(包含由预先构建的类组成的一个集合),您可以使用该接口让任何类都能够通过 foreach                关键字进行循环,就像它是一个数组那样。这个神奇的发明使人们能够采用统一的方式来利用所有 “列表”。但 Iterator                是一个相当复杂的系统,需要您创建一个类,并定义了 4 种方法。有时您希望能够使用一个标准的 foreach                循环,但不希望因为使用一个类结构来存储它而产生开销。
利用较新的生成器 特性,您可以(通过 yield—关键字)让某个函数生成一个值列表,并一次返回一个值。实际上,您可以生成                您想要生成的尽可能多的值,而不必返回任何值。然后,您可以对您的函数使用一个 foreach                循环来检索函数想要收回的所有值。
清单 10 显示了一个简单的示例,一个函数将某一范围内的值划分为相等的部分并返回它们。
清单 10. 一个用来划分各个部分的生成器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
function parts($start, $end, $parts) {
   // Find what our actual length is:
   $length = $end - $start;
   do {
      $start += $length / $parts;
      yield $start;
   } while ($start < $end);
}

// Break 5 feet into 3 parts:
foreach (parts(0, 5, 3) as $l) {
   echo $l, " ";
}
echo "\n";

// Break the range 10-90 into 12 parts:

foreach (parts(10, 90, 12) as $l) {
   echo $l, " ";
}
echo "\n";




第 7 行上发生了神奇的事情,该行上使用了 yield                关键字。实质上,此时函数将停止执行,并返回生成的值。在该函数的后续的每次调用中,都会从它上次停止的地方开始执行,直到生成下一个值或函数终止。
该例子的人为痕迹非常明显,但您可以想象如何使用此技术来获得数据库查询结果,或者使用该技术来解析某个 XML                文件返回的结果。您甚至可以生成键和值,通过使用语法 yield $key => $value 直接模仿数组,如清单                11 中的基于 XML 的示例所示。
清单 11. 使用一个生成器来处理                XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
$xml = <<<EOXML
<?xml version="1.0" encoding="UTF-8" ?>
<products>
  <books>
    <book isbn="978-1940111001">Mastering the SPL Library</book>
    <book isbn="978-1940111056">Functional Programming in PHP</book>
    <book isbn="978-0981034508">Guide to Date and Time Programming</book>
    <book isbn="0973589825">Guide to PHP Design Patterns</book>
  </books>
</products>
EOXML;

$books = function () use ($xml) {
   $products = simplexml_load_string($xml);
   foreach ($products->books->book as $book) {
      yield $book['isbn'] => (string)$book;
   }
};

foreach ($books() as $isbn => $title) {
   echo "{$isbn}: {$title}\n";
}

返回列表