你有没有想过 "在 PHP
中使用 yield 会有什么益处",我将为你节省一些谷歌搜索的时间; 我列出了一些要向你介绍的要点来全面认知 yield:javascript
生成器函数看上去就像一个普通函数, 除了不是返回一个值以外, 生成器会根据需求产生更多的值。php
来看如下的例子:java
function getValues() { yield 'value'; } // 输出字符串 "value" echo getValues();
固然, 这不是他生效的方式, 前面的例子会给你一个致命的错误: 类生成器的对象不能被转换成字符串
, 让咱们清楚的说明:laravel
前面的错误意味着 getValues()
方法不会如预期返回一个字符串,让咱们检查一下他的类型:数组
function getValues() { return 'value'; } var_dump(getValues()); // string(5) "value" function getValues() { yield 'value'; } var_dump(getValues()); // class Generator#1 (0) {}
生成器 类实现了 生成器 接口, 这意味着你必须遍历 getValue()
方法来取值:服务器
foreach (getValues() as $value) { echo $value; } // 使用变量也是好的 $values = getValues(); foreach ($values as $value) { echo $value; }
但这不是惟一的不一样!函数
一个生成器运行你写使用循环来迭代一维数组的代码,而不须要在内存中建立是一个数组,这可能会致使你超出内存限制。性能
在下面的例子里咱们建立一个有 800,000 元素的数字同时从 getValues()
方法中返回他,同时在此期间,咱们将使用函数 memory_get_usage() 来获取分配给次脚本的内存, 咱们将会每增长 200,000 个元素来获取一下内存使用量,这意味着咱们将会提出四个检查点:spa
<?php function getValues() { $valuesArray = []; // 获取初始内存使用量 echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB' . PHP_EOL; for ($i = 1; $i < 800000; $i++) { $valuesArray[] = $i; // 为了让咱们能进行分析,因此咱们测量一下内存使用量 if (($i % 200000) == 0) { // 来 MB 为单位获取内存使用量 echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB'. PHP_EOL; } } return $valuesArray; } $myValues = getValues(); // 一旦咱们调用函数将会在这里建立数组 foreach ($myValues as $value) {}
前面例子发生的状况是这个脚本的内存消耗和输出:.net
0.34 MB
8.35 MB
16.35 MB
32.35 MB
这意味着咱们的几行脚本消耗了超过 30 MB
的内存, 每次你你添加一个元素到 $valuesArray
数组中, 都会增长他在内存中的大小。
让咱们使用 yield 一样的例子:
<?php function getValues() { // 获取内存使用数据 echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB' . PHP_EOL; for ($i = 1; $i < 800000; $i++) { yield $i; // 作性能分析,所以可测量内存使用率 if (($i % 200000) == 0) { // 内存使用以 MB 为单位 echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB'. PHP_EOL; } } } $myValues = getValues(); // 在循环以前都不会有动做 foreach ($myValues as $value) {} // 开始生成数据
这个脚本的输出使人惊讶:
0.34 MB
0.34 MB
0.34 MB
0.34 MB
这不意味着你从 return 表达式迁移到 yield,但若是你在应用中建立会致使服务器上内存出问题的巨大数组,则 yield 更加适合你的状况。
这里有不少 yield 的选项, 我将强调他们中的几个:
a. 使用 yield, 你也可使用 return。
function getValues() { yield 'value'; return 'returnValue'; } $values = getValues(); foreach ($values as $value) {} echo $values->getReturn(); // 'returnValue'
b. 返回键值对:
function getValues() { yield 'key' => 'value'; } $values = getValues(); foreach ($values as $key => $value) { echo $key . ' => ' . $value; }
点击 这里 查看更多。
这个主题的主要缘由是为了明确 yield 和 return 特别是在内存使用方面的区别,使用一些例子是由于我发现他对任何开发人员思考真的很重要。