PHP 函数数组:解释器在计算数组期间意外调用所有函数

PHP array of functions: interpreter unexpectedly calls all functions during evaluation of the array

提问人:Valentino 提问时间:9/2/2022 最后编辑:Valentino 更新时间:9/2/2022 访问量:32

问:

我这里有这个小助手方法:

private function continueConv($attribute, $next): void
{
    $sequence = [   $this->askName(),
                    $this->askEmail(),
                    $this->askPhone(),
                    $this->manageMessage()
                ];

    match($attribute) {
        'user_name' => $sequence[0 + (int)$next], 
        'user_email' => $sequence[1 + (int)$next], 
        'user_phone' => $sequence[2 + (int)$next]
    };

    return;
}

当解释器计算 $sequence 数组时,它不仅存储指向这些函数的指针,还调用它们! 这是一个错误吗? 有可行的替代方案吗? 谢谢


编辑: 有效的替代方法:

private function continueConv($attribute, $next): void
{

    match($attribute) {
        'user_name' => $next ? $this->askEmail() : $this->askName(), 
        'user_email' => $next ? $this->askPhone() : $this->askEmail(), 
        'user_phone' => $next ? $this->manageMessage() : $this->askPhone()
    };

    return;
}

但我更喜欢使用函数数组来轻松更改顺序。


更新:修改后的代码

protected $sequence = [ "run", "askQuestion", "askName", "askEmail", "askPhone", "manageMessage" ];


private function continueConv($fnName, $next): void
{
    $idx = array_search($fnName, $this->sequence) ?: 0;
    $call = [$this, $this->sequence[$idx + (int)$next]]();
}

谢谢大家

PHP 数组 回调

评论

1赞 aynber 9/2/2022
不,它正在做你告诉它做的事情。这些是函数调用,而不是指针。你想达到什么目的?
0赞 Valentino 9/2/2022
我不明白,他们不应该只在我跑步时被调用吗,例如:$sequence[0];
3赞 Your Common Sense 9/2/2022
当然不是。函数应该在你调用它们的地方被调用
1赞 Your Common Sense 9/2/2022
您要查找的称为匿名函数。您可以存储并稍后调用
1赞 Markus Zeller 9/2/2022
只需保留 at 定义,然后存储函数指针即可。 会打电话给第一个。()$sequence$sequence[0]();

答:

1赞 Barmar 9/2/2022 #1

您可以使用包含对象和方法名称的数组作为可调用对象。因此,只需将方法名称放在数组中即可。

private function continueConv($attribute, $next): void
{
    $sequence = ['askName', 'askEmail', 'askPhone', 'manageMessage'];

    $func = [$this, match($attribute) {
        'user_name' => $sequence[0 + $next], 
        'user_email' => $sequence[1 + $next], 
        'user_phone' => $sequence[2 + $next]
    }];

    $func();
}

评论

0赞 mickmackusa 9/2/2022
$func是一次性声明,因此可以安全地省略。只需在阵列关闭后将其捶打即可。我不知道我是否喜欢提问者在这里的设计选择。 要求所有分支都为之代言或具有默认分支,对吗?因此,这意味着开发人员需要非常小心地对所有潜在结果进行硬编码。我可能会删除一些模糊性,并创建带有下划线和方法名称字符串的键的关联查找。然后值可以只检查查找,如果 ,则抛出异常。()]match()$attribute!method_exists()
1赞 Barmar 9/2/2022
@mickmackusa我喜欢把它分成多个陈述,以使事情更清楚,尤其是在 SO 答案中。由于增量变量,assoc 数组在这里似乎不起作用,$next
0赞 mickmackusa 9/2/2022
是的,你是对的,这方面确实会带来麻烦。$next