You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP可选生成器函数实现咨询:单/多值场景适配

PHP可选生成器函数的实现困境

我在开发中需要实现这样一个函数:当需要返回多个值时作为生成器,仅返回单个值时作为普通函数,但在PHP中遇到了实现困难。

根据PHP官方文档:

任何包含yield关键字的函数都是生成器函数。

这条规则看似简单,但实际开发中存在问题:只要函数里包含yield,哪怕该yield语句永远不会被执行,函数也会被标记为生成器函数。比如下面的代码:

function generatorTest() {
    if(false) {
        yield 0;
    } else {
        return 0;
    }
}

var_dump(generatorTest()); // object(Generator)

预期会返回int类型,但实际返回的是Generator对象。

现有尝试的方案

方案一:通过闭包返回生成器

将生成器逻辑封装在闭包中,让主函数根据条件返回闭包生成的生成器或普通值:

function generatorTest() {
    if(false) {
        return (function() {
            yield 0;
        })();
    } else {
        return 0;
    }
}

var_dump(generatorTest()); // int(0)

该方案可行,但代码冗余度高,在处理复杂API请求迭代的场景下,会导致大量重复代码,实用性差。

方案二:始终生成生成器,通过异常判断返回类型

先创建生成器,再尝试获取其返回值,捕获异常则返回生成器本身:

function generatorTest() {
    $ret = (function() {
        if(false) {
            yield 0;
        } else {
            return 0;
        }
    })();
    
    try {
        return $ret->getReturn();
    } catch(Exception $e) {
        return $ret;
    }
}

var_dump(generatorTest()); // int(0)

该方案避免了代码冗余,但依赖捕获异常来判断返回类型,实现不够优雅。

应用场景细节

我正在开发MediaWiki机器人,其中一个用于查询维基百科修订记录的函数需要根据参数返回不同结果:传入单个ID时返回单条记录,传入多个ID时返回生成器以便逐个遍历记录。

目前使用方案二,但该方案需要预加载所有数据后再返回生成器,完全失去了生成器的高效性,处理大量请求时需等待很久才能看到结果。

调用示例

单ID调用:

require_once("bottibott_v5/src/autoload.php");

$bot = new Bot(URL); // URL为维基API端点地址
$revisions = new Revisions($bot);
$revisions->setIds("1");

var_dump($revisions->getRevisionsFromRevids()); // 输出单条修订记录

多ID调用:

require_once("bottibott_v5/src/autoload.php");

$bot = new Bot(URL); // URL为维基API端点地址
$revisions = new Revisions($bot);
$revisions->setIds(range(0, 10));

foreach($revisions->getRevisionsFromRevids() as $revision) {
    var_dump($revision); // 逐个输出修订记录
}

求助问题

是否有更优的方式实现这种可选生成器函数?是否需要调整设计思路?还是当前的方案已是最优解?

内容的提问来源于stack exchange,提问作者RobbiRobb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 18:23:16