一个php进程可以处理包含亿级数量的数组么?答案Yes

在之前很多人的认知中,php的原则是quick and dirty,我认为这有一定道理.无论从编码的设计思路还是其特殊的垃圾回收机制都证明着这个观点.

随着时间的推移,PHP的年纪越来越大,喷的人越来越多,但是丝毫没有影响PHP在web世界的霸主地位. 原因是多种多样的. 我认为无论何种编程语言都是为产品服务的,那么只要能稳定,合格的实现产品功能,就可以说这门语言是成功的.

在这个基础上PHP还拥有开发速度快,入门成本低等先天优势,那么风靡世界就是自然而然的事情了. 我很不理解某些自命不凡或者自命清高的程序员,任何职业都是要接地气的,尤其是在中国.实现产品功能是硬性条件,在这个基础上尽量控制开发成本已经开发时间,这是很浅显的道理.不需要多么优雅,我们伟大的party也是农民阶级建立并解放新中国的.简单直接才是硬道理.

好了,不扯一些别的东西了. 最近PHP的大事是5.5 release了,里面有一些有趣的东西. 今天介绍一下Generators这个东东,有一些技术博客将它翻译成生成器, 官方给出的介绍是这样的:Generators provide an easy way to implement simple iterators without the overhead or complexity of implementing a class that implements the Iterator interface.
我理解的意思就是一个简单实现的迭代器. 有了它,php能做的事情更多了.比如说:

function xrange($start, $end, $step = 1) {
    for ($i = $start; $i <= $end; $i += $step) {
        yield $i;
    }
}
foreach (xrange(1, 1000000) as $num) {
    echo $num, "\n";
}

 
上面这个xrange函数提供了和PHP的内建函数range一样的功能。但是不同的是range()函数返回的是一个包含属组值从1到100万的数组(注:请查看手册)。
而xrange函数返回的是依次输出这些值的一个迭代器,而且并不会真正以数组形式计算。 这种方法的优点是显而易见的。它可以让你在处理大数据集合的时候不用一次性的加载到内存中。甚至你可以处理无限大的数据流。 当然,也可以不同通过生成器来实现这个功能,而是可以通过继承Iterator接口实现。通过使用生成器实现起来会更方便,而不用再去实现iterator接口中的5个方法了。 要从生成器认识协同程序,理解它们内部是如何工作的非常重要:生成器是可中断的函数,在它里面,yield构成了中断点。

紧接着上面的例子,如果你调用xrange(1,1000000)的话,xrange()函数里代码没有真正地运行。相反,PHP只是返回了一个实现了迭代器接口的生成器类实例
你对某个对象调用迭代器方法一次,其中的代码运行一次。例如,如果你调用$range->rewind(),那么xrange()里的代码运行到控制流 第一次出现yield的地方。在这种情况下,这就意味着当$i=$start时yield $i才运行。传递给yield语句的值是使用$range->current()获取的。
为了继续执行生成器中的代码,你必须调用$range->next()方法。这将再次启动生成器,直到yield语句出现。因此,连续调用next()和current()方法 你将能从生成器里获得所有的值,直到某个点没有再出现yield语句。对xrange()来说,这种情形出现在$i超过$end时。在这中情况下, 控制流将到达函数的终点,因此将不执行任何代码。一旦这种情况发生,vaild()方法将返回假,这时迭代结束。 再举一个例子: 假如有一个巨大的文件,  

function getLinesFromFile($fileName) {
  if (!$fileHandle = fopen($fileName, 'r')) {
    return;
  }

  while (false !== $line = fgets($fileHandle)) {
    yield $line;
  }

  fclose($fileHandle);
}

我们通过简单的 生成器就可以用一个php进程处理整个文件,只是时间问题而已.

$filename = 'somefile.txt';
$gen = getLinesFromFile($filename);

foreach ($gen as $line) {
  echo $line;
}

引自一个老外的测试结果,还是很惊喜的.

0E4E064A-D25E-4A16-8332-6A5FF080D54D
PHP 5.5给我们的惊喜还不止于此.而且作为一门有一些历史的语言(想比较node,go等)保持高速的进步实属不易,现在官方需要做的是如何加速php世界的版本更新,这个尤为重要. 其实我更想看到的是php能够更加实用和具体的功能,比如: 函数重载. 错误异常中继而不是简单的输出.