提问人:Valentino 提问时间:9/2/2022 最后编辑:Valentino 更新时间:9/2/2022 访问量:32
PHP 函数数组:解释器在计算数组期间意外调用所有函数
PHP array of functions: interpreter unexpectedly calls all functions during evaluation of the array
问:
我这里有这个小助手方法:
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]]();
}
谢谢大家
答:
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
评论
()
$sequence
$sequence[0]();