
本文旨在深入探讨在 PHP 中如何通过字符串名称或值获取枚举(Enum)成员的实用策略。我们将详细介绍利用支持枚举(Backed Enums)的 `tryFrom` 或 `from` 方法,以及为纯枚举(Pure Enums)实现自定义静态查找功能,旨在解决在不重复定义字符串值的情况下进行高效查找的需求。
在 PHP 8.1 及更高版本中引入的枚举(Enums)为定义一组有限的常量值提供了强大的类型安全机制。在实际开发中,我们经常需要根据一个字符串(例如,从用户输入、API 请求或数据库中获取)来查找并获取对应的枚举成员。本文将详细介绍两种主要的方法来解决这一常见需求。
PHP 枚举分为两种类型:纯枚举(Pure Enums)和支持枚举(Backed Enums)。支持枚举允许每个枚举成员关联一个标量值(字符串或整数),这为通过这些值进行查找提供了便利的内置机制。
要创建一个支持枚举,你需要为它指定一个类型(string 或 int),并为每个成员提供一个相应类型的值。
立即学习“PHP免费学习笔记(深入)”;
<?php
enum Status: string
{
case OK = "OK";
case FAILED = "FAILED";
case PENDING = "PENDING";
}在这个例子中,Status 枚举的每个成员都关联了一个字符串值。值得注意的是,为了通过成员的名称(例如 "OK")进行查找,我们通常会将成员的名称作为其关联值,尽管这正是用户最初试图避免的“重复定义”。
支持枚举提供了两个静态方法来根据其关联值进行查找:
示例代码:
<?php
// 定义支持枚举
enum Status: string
{
case OK = "OK";
case FAILED = "FAILED";
case PENDING = "PENDING";
}
// 使用 tryFrom 进行查找
$status1 = Status::tryFrom("OK"); // 返回 Status::OK
$status2 = Status::tryFrom("UNKNOWN"); // 返回 null
$status3 = Status::tryFrom("pending"); // 返回 null (区分大小写)
// 使用 from 进行查找 (注意异常处理)
try {
$status4 = Status::from("FAILED"); // 返回 Status::FAILED
$status5 = Status::from("NONEXISTENT"); // 抛出 ValueError
} catch (ValueError $e) {
echo "错误: " . $e->getMessage() . "\n";
}
// 获取枚举成员的名称和值
echo "Status::OK 的名称: " . Status::OK->name . "\n"; // 输出: OK
echo "Status::OK 的值: " . Status::OK->value . "\n"; // 输出: OK优点:
局限性:
当你不希望为每个枚举成员重复定义一个与其名称相同的字符串值时,纯枚举结合自定义静态方法是一个更灵活的选择。纯枚举不关联任何标量值,但每个枚举成员都隐式地拥有一个 name 属性,其值为该成员的声明名称。
纯枚举的定义不指定任何类型或关联值:
<?php
enum Status
{
case OK;
case FAILED;
case PENDING;
}我们可以为纯枚举添加一个自定义的静态方法,该方法遍历所有枚举成员,并将其 name 属性与输入的字符串进行比较。
示例代码:
<?php
enum Status
{
case OK;
case FAILED;
case PENDING;
/**
* 根据字符串名称查找对应的 Status 枚举成员。
* 支持不区分大小写和去除空格。
*
* @param string $name 要查找的名称字符串。
* @return self|null 找到的 Status 枚举成员,如果未找到则返回 null。
*/
public static function get(string $name): ?self
{
// 清理输入字符串:去除首尾空格并转换为大写,以实现不区分大小写的查找
$cleanedName = strtoupper(trim($name));
// 如果清理后的名称为空,则直接返回 null
if (empty($cleanedName)) {
return null;
}
// 遍历所有 Status 枚举成员
foreach (Status::cases() as $status) {
// 比较成员的名称(大写)与清理后的输入名称
if (strtoupper($status->name) === $cleanedName) {
return $status;
}
}
// 如果遍历结束后仍未找到匹配项,则返回 null
return null;
}
}
// 使用自定义的 get 方法进行查找
$status1 = Status::get("OK"); // 返回 Status::OK
$status2 = Status::get("failed"); // 返回 Status::FAILED (由于内部转换为大写)
$status3 = Status::get(" pending "); // 返回 Status::PENDING (去除空格并转换为大写)
$status4 = Status::get("UNKNOWN"); // 返回 null
$status5 = Status::get(""); // 返回 null
// 获取纯枚举成员的名称
echo "Status::OK 的名称: " . Status::OK->name . "\n"; // 输出: OK实现原理:
优点:
注意事项:
在决定使用哪种方法时,请考虑以下因素:
是否有业务关联值?
是否仅通过成员名称查找,且不希望重复定义值?
代码简洁性与可维护性:
在 PHP 中通过字符串获取枚举成员,主要有两种策略:
根据你的具体需求和对代码简洁性、灵活性以及数据冗余的权衡,选择最适合你的方法。在大多数情况下,如果枚举的名称本身就是你想要查找的字符串,自定义的 get 方法可以提供一个更“纯粹”的解决方案,避免了 Backed Enum 中名称与值重复的问题。
以上就是PHP 枚举成员字符串查找指南的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号