
本文旨在解决在 php 中如何根据字符串名称获取非 backed enum 的枚举案例。由于非 backed enum 不支持 `tryfrom` 或 `from` 方法,文章将详细介绍通过自定义静态方法遍历枚举所有案例并进行名称匹配的实现方案,并提供示例代码和相关注意事项,帮助开发者有效管理和使用非 backed enum。
PHP 8.1 引入了枚举(Enums),为开发者提供了一种定义一组命名常量的新方式。在 PHP 中,枚举分为两种主要类型:
纯枚举(Pure Enums / Plain Enums):这类枚举只包含案例名称,没有关联的具体值。例如:
<?php
enum Status
{
case OK;
case FAILED;
case PENDING;
}
?>对于纯枚举的案例,可以通过 Status::OK->name 获取其字符串名称 "OK"。
支持值枚举(Backed Enums):这类枚举的每个案例都关联一个具体的值,可以是字符串或整数。例如:
立即学习“PHP免费学习笔记(深入)”;
<?php
enum Status: string // 指定关联值为字符串类型
{
case OK = "success";
case FAILED = "failure";
case PENDING = "waiting";
}
?>支持值枚举的案例除了 name 属性外,还拥有 value 属性,例如 Status::OK->value 将返回 "success"。更重要的是,Backed Enums 提供了 from() 和 tryFrom() 静态方法,允许开发者通过关联值(而非案例名称)直接获取对应的枚举案例。例如 Status::tryFrom("success") 将返回 Status::OK。
开发中常见的一种需求是,给定一个字符串(通常是枚举案例的名称),需要获取对应的枚举案例实例。对于 Backed Enum,如果字符串恰好是其关联值,可以直接使用 tryFrom() 方法。然而,对于纯枚举,我们没有关联值,也无法直接使用 tryFrom() 方法(因为它期望的是关联值而不是案例名称)。
例如,我们希望实现类似 Status::get("OK") 的功能,使其返回 Status::OK 实例,但又不希望将 Status 定义为 Backed Enum(即避免 case OK = "OK"; 这种重复定义)。
由于 PHP 的纯枚举没有内置的通过名称查找案例的方法,最直接和推荐的解决方案是在枚举类内部实现一个自定义的静态方法来完成此功能。核心思路是遍历枚举的所有案例,并比较每个案例的 name 属性与传入的字符串是否匹配。
以下是一个实现此功能的示例代码:
<?php
enum Status
{
case OK;
case FAILED;
case PENDING;
/**
* 根据字符串名称获取对应的枚举案例。
*
* @param string $name 要查找的枚举案例名称。
* @return Status|null 如果找到匹配的案例,则返回该案例实例;否则返回 null。
*/
public static function get(string $name): ?Status
{
// 对输入名称进行清理,例如转换为大写并去除空白,以实现更灵活的匹配。
// 这样做可以处理 "ok", " OK " 等不同格式的输入。
$normalizedName = strtoupper(trim($name));
// 避免空字符串查询导致不必要的遍历
if (empty($normalizedName)) {
return null;
}
// 遍历枚举类的所有案例
foreach (self::cases() as $status) {
// 比较枚举案例的名称属性与标准化后的输入名称
if ($status->name === $normalizedName) {
return $status; // 找到匹配项,返回该案例
}
}
// 未找到匹配的案例则返回 null
return null;
}
}
// 示例用法
$statusOk = Status::get("OK"); // 返回 Status::OK
$statusFailed = Status::get(" failed "); // 经过内部处理,返回 Status::FAILED
$statusPending = Status::get("pending"); // 经过内部处理,返回 Status::PENDING
$statusNotFound = Status::get("UNKNOWN"); // 未找到,返回 null
var_dump($statusOk);
var_dump($statusFailed);
var_dump($statusPending);
var_dump($statusNotFound);
// 输出示例:
// object(Status)#1 (0) {
// }
// object(Status)#2 (0) {
// }
// object(Status)#3 (0) {
// }
// NULL
?>尽管 PHP 的纯枚举没有像 Backed Enum 那样内置 tryFrom() 或 from() 方法来通过字符串名称获取案例,但通过在枚举类中实现一个自定义的静态查找方法,可以优雅且高效地解决这一问题。这种方法利用了 self::cases() 提供的所有枚举案例列表,结合字符串处理和比较逻辑,实现了灵活的案例查找功能,同时保持了代码的清晰性和可维护性。理解纯枚举和 Backed Enum 的区别,并根据具体需求选择合适的实现方式,是有效利用 PHP 枚举的关键。
以上就是PHP 枚举:从字符串获取非 Backed Enum 案例的实现方法的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号