在 PHP 中使用带有 Match 表达式的值数组

Using an Array of values with a Match Expression in PHP

提问人:Ben Carey 提问时间:8/21/2021 更新时间:8/22/2021 访问量:1891

问:

有没有办法将数组用作值列表,以便在 PHP 的匹配表达式中进行匹配

考虑一下:

return match ($field) {
    'id', 'first_name', 'last_name', 'updated_at', 'created_at' => (string) $item->{$field},
    'image' => $item->{$field}->getUrls(),
    'balance' => (int) $item->{$field},
    default => null
};

虽然上述方法有效,但我想以更易读/更易于管理的方式格式化匹配语句。例如,我在数据转换器上使用上述表达式在我的 API 中呈现数据;因此,我发现自己处于以一种格式返回许多字段的情况,并且以以下方式(或类似方式)表示它会更具可读性:

$string_columns = ['id', 'first_name', 'last_name', 'updated_at', 'created_at'];

return match ($field) {
    $string_columns => (string) $item->{$field},
    'image'         => $item->{$field}->getUrls(),
    'balance'       => (int) $item->{$field},
    default         => null
};
PHP 匹配 php-8

评论

1赞 Robo Robok 8/22/2021
不知道你是否知道这一点,但你不需要大括号 - 它会很好用,因为$item->{$field}$item->$field
0赞 Ben Carey 8/22/2021
@RoboRobok - 啊,我没知道......这是 PHP 8 中的新功能吗?如果没有,不知道为什么我一开始就在那里
0赞 Robo Robok 8/22/2021
不,我已经这样做了很长时间:)

答:

4赞 Robo Robok 8/21/2021 #1

你的问题启发了我检查是否适用于声明,但它没有。...$string_columnsmatch

我认为除了技巧之外,没有任何方法可以做到这一点。match

我想到的一个技巧是创建一个辅助函数,仅当它在数组中时才返回该值:

function any(array $values, $value)
{
    return in_array($value, $values, true) ? $value : null;
}

$string_columns = ['id', 'first_name', 'last_name', 'updated_at', 'created_at'];

return match ($field) {
    any($string_columns, $field) => (string) $item->{$field},
    'image'                      => $item->{$field}->getUrls(),
    'balance'                    => (int) $item->{$field},
    default                      => null
};

有点啰嗦,但会起作用。

我认为它值得理解为一种只适合某些场景的语言结构。match

评论

0赞 Błażej Kowalczyk 8/21/2021
这段代码会破坏女巫 $field==null - 它会尝试 $item->{null};顺便说一句,...$array在比赛中会很好
0赞 Robo Robok 8/21/2021
当然,它会与 null 一起使用,但您不会将它与 null 一起使用。
1赞 Ben Carey 8/22/2021
我同意,我已经尝试了各种方法,如果没有稍微肮脏的解决方法,这似乎是不可能的。我会将这个标记为接受的答案,只是因为你先发布了它。这两个答案都是有创意的,老实说,我真的没有偏爱任何一个。话虽如此,我想我可以将其提取到全局帮助函数中,然后在我需要它的任何地方使用它,而另一个答案是,这是不可能的。谢谢:-D
0赞 Robo Robok 8/22/2021
@BenCarey我很高兴,谢谢你选择我的答案。我想知道是否会在某个时候起作用。也许是PHP 8.1?...$array
0赞 Ben Carey 8/22/2021
@RoboRobok - 人们希望,这似乎是不言自明的......
0赞 Błażej Kowalczyk 8/21/2021 #2

这是不可能的。只需在默认值中添加in_array即可。

return match ($field) {
    'image'         => $item->{$field}->getUrls(),
    'balance'       => (int) $item->{$field},
    default => in_array($value, $string_columns, true) ? 
              (string) $item->{$field} 
              : null;
};

如果会有更多的数组,你可以链接三元运算符

评论

1赞 Robo Robok 8/22/2021
您可能希望删除$string_columns => (string) $item->{$field},
0赞 Ben Carey 8/22/2021
谢谢你的回答 - 我接受了另一个,只是因为它是先发布的,而且因为它在技术上可以在整个项目中重用,而这个只能在每个匹配表达式中使用一次,这并不理想