当前位置:首页 > CN2资讯 > 正文内容

Generators in PHP

3天前CN2资讯


If you’ve followed my previous posts about iterators then you’ll know that iteration is an important programming concept, but implementing the required interfaces to create an iterable object can be a hassle at best because of the amount of boilerplate code that is required. With the release of PHP 5.5, we finally have generators!

In this article we’ll take a look at generators which provide an easy way to implement simple iterators without the overhead or complexity of the Iterator interface.

How do Generators Work?

According to Wikipedia, a generator “is very similar to a function that returns an array, in that a generator has parameters, can be called, and generates a sequence of values”. A generator is basically a normal function, but instead of returning a value it yields as many values as it needs to. It looks like a function but acts like an iterator.

Generators use the yield keyword instead of return. It acts similar to return in that it returns a value to the caller of the function, but instead of removing the function from the stack, yield saves its state. This allows the function to continue from where it was when it’s called again. In fact, you cannot return a value from a generator although you can use return without a value to terminate its execution.

The PHP manual states: “When a generator function is called, it returns an object that can be iterated over.” This is an object of the internal Generator and implements the Iterator in the same way a forward-only iterator object does. As you iterate over that object, PHP calls the generator each time it needs a value. The state is saved when the generator yields so that it can be resumed when the next value is required.

<?php function nums() { echo "The generator has startedn"; for ($i = 0; $i < 5; ++$i) { yield $i; echo "Yielded $in"; } echo "The generator has endedn"; } foreach (nums() as $v);

The output of the above code will be:


The generator has started Yielded 0 Yielded 1 Yielded 2 Yielded 3 Yielded 4 The generator has ended


Our First Generator

Generators are not a new concept and already exist in languages such as C#, Python, JavaScript, and Ruby (enumerators), and are usually identified by their use of the yield keyword. The following is an example in Python:

def file_lines(filename): file = open(filename) for line in file: yield line file.close() for line in file_lines('somefile'): #do some work here

Let’s rewrite the example Python generator in PHP. (Note that both snippets do not perform any sort of error checking.)

<?php function file_lines($filename) { $file = fopen($filename, 'r'); while (($line = fgets($file)) !== false) { yield $line; } fclose($file); } foreach (file_lines('somefile') as $line) { // do some work here }

The generator function opens a file and then yields each line of the file as and when it is required. Each time the generator is called, it continues from where it left off. It doesn’t start from the beginning again as its state had been saved when the yield statement was executed. Once all lines have been read, the generator simply terminates and the loop ends.

Returning Keys

PHP iterators consist of key/value pairs. In our example, only a value was returned and therefore the keys were numeric (keys are numeric by default). If you wish to return an associative pair, simply change the yield statement to include the key using array syntax.

<?php function file_lines($filename) { ... yield $key => $line; ... } foreach (file_lines('somefile') as $key => $line) { // do some work here }

Injecting Values

yield does not only return values; it can receive values from the outside as well. This is done by calling the send() of the generator object with the value you wish to pass. This value can then be used in computing or doing other stuff. The method sends the value to the generator as a result of the yield expression and resumes execution.

<?php function nums() { for ($i = 0; $i < 5; ++$i) { // get a value from the caller $cmd = (yield $i); if ($cmd == 'stop') { return; // exit the generator } } } $gen = nums(); foreach ($gen as $v) { // we are satisfied if ($v == 3) { $gen->send('stop'); } echo "{$v}n"; }

The output will be:


0 1 2 3


Saving Memory with Generators

Generators are great for when you are calculating large sets and you don’t want to allocate memory for all of the results at the same time or when you don’t know if you will need all of the results, Due to the way results are processed, the memory footprint can be reduced to a very bare minimum by allocating memory for only the current result.

Imagine the file() function which returns all of the lines in a file as an array. Running a simple benchmark for file() and our demo file_lines() functions, each using the same random 100 paragraph text file generated using Lipsum, showed the file function used up to 110 times more memory than the generator.

<?php // Test 1 $m = memory_get_peak_usage(); foreach (file_lines('lipsum.txt') as $l); echo memory_get_peak_usage() - $m, "n"; //Outputs 7336 // Test 2 $m = memory_get_peak_usage(); foreach (file('lipsum.txt') as $l); echo memory_get_peak_usage() - $m, "n"; // Outputs 148112
    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/26264.html

    分享给朋友:

    “Generators in PHP” 的相关文章

    远程VPS优选指南:高效管理虚拟专用服务器的最佳实践

    随着远程工作的普及和数字化转型的加速,远程VPS(虚拟专用服务器)逐渐成为许多企业和个人的首选工具。VPS通过虚拟化技术,让我们能够在一台物理服务器上同时运行多个独立的操作系统,这种灵活性使得用户能够像管理独立服务器那样,远程登录和管理自己的虚拟环境。每天都有更多的人意识到,拥有一个VPS可以为他们...

    VPS商家全攻略:选择适合你的虚拟专用服务器

    VPS商家概述 在数字化时代,VPS(虚拟专用服务器)服务逐渐成为企业和个人用户的重要选择。VPS不仅为用户提供了灵活性,而且在性能、控制权和安全性上都优于传统的共享主机。这使它成为许多需要独立环境来运行网站或应用程序的用户的理想解决方案。 选择VPS的用户通常追求更高的稳定性和可靠性。相比于共享主...

    阿里云国际:企业数字化转型的理想云服务解决方案

    阿里云国际概述 阿里云国际成立于2015年,致力于为全球用户提供高效、可靠、安全的云计算服务。作为阿里巴巴集团的一部分,阿里云国际不仅承载着国内市场的技术精华,也积极拓展国际市场。随着全球互联网的快速发展,企业对云服务的需求不断增加,阿里云国际顺应这一趋势,凭借创新的技术和丰富的经验,迅速在全球范围...

    内部错误解决指南:快速识别与处理方法

    一说到“内部错误”,我们很多人可能会感到一头雾水。其实,内部错误是指在计算机系统或程序内部发生的那种错误。这类错误通常是由于系统内部的某些故障所造成的,或是程序代码本身的一些问题。如果我们把计算机比作一个庞大的工厂,那么内部错误就像是工厂里机器运转不畅或部件失灵,导致整个生产线出现问题。 理解内部错...

    如何使用Windows网络诊断工具查找服务器地址和解决网络问题

    在当今这个网络无处不在的时代,能够快速诊断网络问题已变得尤为重要。作为Windows用户,我们的设备中自带了一个非常实用的工具——Windows网络诊断工具。说到这个工具,许多人可能不太了解它的具体功能和用途。 Windows网络诊断工具是一个集成在Windows操作系统中的应用,专门用于帮助用户识...

    iHerb折扣攻略:轻松获取最佳优惠和值得购买的健康产品

    1.1 iHerb 平台简介 iHerb 是一个备受欢迎的在线购物平台,专注于健康和营养产品。我第一次接触 iHerb 是在寻找一些天然补品和有机食品的时候,发现这个网站不仅产品种类丰富,还提供了详细的产品信息和用户评价,帮助我做出明智的购买决策。无论是维生素、矿物质,还是植物提取物和美容护肤品,i...