php如何生成控制器_PHP中的生成器

php如何生成控制器

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!

如果您已经阅读了之前关于迭代器的文章,那么您就会知道迭代是一个重要的编程概念,但是实现所需的接口以创建可迭代的对象最多可能很麻烦,因为需要大量的样板代码。 随着PHP 5.5的发布,我们终于有了生成器!

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.

在本文中,我们将研究生成器,这些生成器提供了一种实现简单迭代器的简便方法,而又没有Iterator接口的开销或复杂性。

发电机如何工作? (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.

根据Wikipedia的说法,生成器“与返回数组的函数非常相似,因为生成器具有参数,可以被调用,并生成值序列”。 生成器基本上是一个正常的函数,但是它不返回值而是产生所需数量的值。 它看起来像一个函数,但就像一个迭代器。

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.

生成器使用yield关键字而不是return 。 它的行为类似于return,它向函数的调用者返回一个值,但是yield不会从堆栈中删除该函数,而是保存其状态。 这使函数可以从再次调用时的位置继续。 实际上,尽管可以使用没有值的return来终止其执行,但是您无法从生成器return值。

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 class and implements the Iterator interface 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手册指出:“调用生成器函数时,它将返回可以迭代的对象。” 这是内部Generator的对象,并以仅转发迭代器对象的相同方式实现Iterator接口 。 遍历该对象时,PHP每次需要一个值时都会调用生成器。 当发生器屈服时将保存状态,以便在需要下一个值时可以恢复状态。

<?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:

生成器不是一个新概念,并且已经存在于C#,Python,JavaScript和Ruby(枚举器)等语言中,并且通常通过使用yield关键字进行标识。 以下是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重写示例Python生成器。 (请注意,两个代码段均不执行任何类型的错误检查。)

<?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.

生成器函数将打开一个文件,然后在需要时生成文件的每一行。 每次调用生成器时,它将从中断处继续。 它不再从头开始,因为执行yield语句时已保存其状态。 读取所有行后,生成器将简单终止并结束循环。

返回键 (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迭代器由键/值对组成。 在我们的示例中,仅返回一个值,因此键为数字(默认情况下,键为数字)。 如果要返回关联对,只需使用数组语法更改yield语句以包含键。

<?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() method 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.

yield不仅返回值; 它也可以从外部接收值。 这可以通过使用您希望传递的值调用生成器对象的send()方法来完成。 然后可以将此值用于计算或做其他事情。 该方法将值作为yield表达式的结果发送给生成器,然后继续执行。

<?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.

想象一下file()函数,它将file()所有行作为数组返回。 对file()和我们的演示file_lines()函数运行一个简单的基准,每个函数都使用通过Lipsum生成的相同的随机100段文本文件,显示该文件函数使用的内存比生成器多110倍。

<?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

结论 (Conclusion)

With the introduction of Generators, PHP has placed a powerful tool into the hands of developers. We can now write iterators rapidly while saving a lot of memory in the process. With this tutorial, I hope you have gained enough to start using them yourself in your projects. I for one have quite a few objects in mind that I am going to rewrite. If you have any ideas or comments, drop them.

随着Generators的引入,PHP为开发人员提供了强大的工具。 现在,我们可以快速编写迭代器,同时节省大量内存。 通过本教程,希望您获得足够的知识,可以开始在项目中自己使用它们。 我要记住很多要重写的对象。 如果您有任何想法或意见,请将其删除。

翻译自: https://www.sitepoint.com/generators-in-php/

php如何生成控制器

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值