PHP 枚举:根据字符串获取枚举案例的策略与实现


php 枚举:根据字符串获取枚举案例的策略与实现

本文旨在探讨在 PHP 中如何根据字符串值获取枚举(Enum)的对应案例。我们将重点介绍 `BackedEnum` 的原生 `tryFrom()` 方法,以及针对纯枚举(Pure Enum)没有显式字符串值时,如何通过自定义静态方法遍历枚举案例并匹配其名称来实现这一功能,并提供详细代码示例。

在 PHP 8.1 及更高版本中引入的枚举(Enums)为定义一组有限的、命名常量集合提供了一种强大且类型安全的方式。在实际应用中,我们经常需要根据一个字符串(例如,来自用户输入或数据库)来获取对应的枚举案例(Enum Case)。这在处理不同类型的枚举时,其实现方式有所不同。

1. 使用 Backed Enums 的原生方法:tryFrom() 和 from()

如果您的枚举是“支持枚举”(Backed Enum),即每个枚举案例都关联了一个显式的标量值(字符串或整数),那么 PHP 提供了一个非常方便的原生方法来根据这些值获取枚举案例。

什么是 Backed Enum? Backed Enum 的每个案例都必须声明一个唯一的标量值。例如:

<?php
enum Status: string // 声明为 Backed Enum,支持字符串值
{
    case OK = "OK";
    case FAILED = "FAILED";
    case PENDING = "PENDING";
}
?>

获取枚举案例 对于 Backed Enum,可以使用 tryFrom() 或 from() 方法根据其关联的字符串或整数值来获取对应的枚举案例。

  • tryFrom(string|int $value): ?self: 尝试从给定的值获取枚举案例。如果找不到匹配的案例,它将返回 null,而不会抛出错误。
  • from(string|int $value): self: 从给定的值获取枚举案例。如果找不到匹配的案例,它将抛出 ValueError 异常。

示例代码:

<?php
enum Status: string
{
    case OK = "OK";
    case FAILED = "FAILED";
    case PENDING = "PENDING";
}

// 使用 tryFrom()
$statusFromOk = Status::tryFrom("OK");     // 返回 Status::OK
$statusFromPending = Status::tryFrom("PENDING"); // 返回 Status::PENDING
$statusFromInvalid = Status::tryFrom("UNKNOWN"); // 返回 null

var_dump($statusFromOk);
var_dump($statusFromInvalid);

// 使用 from() (会抛出异常,通常需要try-catch)
try {
    $statusFromFailed = Status::from("FAILED"); // 返回 Status::FAILED
    var_dump($statusFromFailed);
    $statusFromNonExistent = Status::from("NON_EXISTENT"); // 抛出 ValueError
} catch (ValueError $e) {
    echo "Error: " . $e->getMessage() . "\n";
}
?>

这种方式是获取 Backed Enum 案例的首选方法,因为它简洁、高效且是 PHP 原生支持的。

2. 纯枚举(Pure Enums)的挑战与自定义解决方案

什么是 Pure Enum? 纯枚举(Pure Enum)的案例没有显式关联的标量值。它们仅仅是命名常量。例如:

<?php
enum Action // 纯枚举,没有声明 : string 或 : int
{
    case CREATE;
    case READ;
    case UPDATE;
    case DELETE;
}
?>

对于纯枚举,tryFrom() 和 from() 方法是不可用的,因为它们没有底层值可供匹配。然而,每个枚举案例都有一个内部的名称(name)属性,它是一个字符串,与声明的案例名称完全一致。例如,Action::CREATE->name 将返回字符串 "CREATE"。

问题: 如何根据一个字符串(例如 "CREATE")来获取 Action::CREATE 这个枚举案例?

Freepik Mystic Freepik Mystic

Freepik Mystic 是一款革命性的AI图像生成器,可以直接生*高清图像

Freepik Mystic 174 查看详情 Freepik Mystic

解决方案: 由于没有原生方法,我们需要编写一个自定义的静态方法来遍历所有可用的枚举案例,并将其 name 属性与输入的字符串进行比较。

实现自定义 get() 方法

我们可以在枚举内部添加一个静态方法,例如 get(),来封装这个逻辑:

<?php
enum Status
{
    case OK;
    case FAILED;
    case PENDING;

    /**
     * 根据字符串名称获取对应的枚举案例。
     * 支持大小写不敏感和去除空格。
     *
     * @param string $name 要查找的枚举案例名称。
     * @return self|null 匹配的枚举案例,如果未找到则返回 null。
     */
    public static function get(string $name): ?self
    {
        // 对输入名称进行预处理,例如转换为大写并去除首尾空格,
        // 以实现更灵活的匹配。
        $normalizedName = strtoupper(trim($name));

        if (empty($normalizedName)) {
            return null; // 空字符串无法匹配
        }

        // 遍历所有枚举案例
        foreach (self::cases() as $status) {
            // 比较当前案例的名称与标准化后的输入名称
            if ($status->name === $normalizedName) {
                return $status;
            }
        }

        return null; // 未找到匹配的案例
    }
}

// 使用自定义的 get() 方法
$statusOk = Status::get("OK");       // 返回 Status::OK
$statusFailed = Status::get("failed"); // 返回 Status::FAILED (由于 strtoupper)
$statusPending = Status::get("  PENDING  "); // 返回 Status::PENDING (由于 trim)
$statusInvalid = Status::get("UNKNOWN"); // 返回 null

var_dump($statusOk);
var_dump($statusFailed);
var_dump($statusPending);
var_dump($statusInvalid);

// 访问枚举案例的名称属性
echo "Status::OK 的名称是: " . Status::OK->name . "\n"; // 输出 "OK"
?>

代码解析:

  1. self::cases(): 这是一个 PHP 枚举的内置静态方法,它返回一个包含所有枚举案例的数组。
  2. strtoupper(trim($name)): 这行代码对输入的字符串进行了预处理。trim() 去除了字符串两端的空白字符,strtoupper() 将字符串转换为大写。这样做可以使查找功能更健壮,允许用户输入大小写不敏感或带有额外空格的名称。
  3. $status->name: 每个枚举案例都有一个只读的 name 属性,它返回该案例的字符串名称(例如,对于 case OK;,name 就是 "OK")。
  4. 循环比较: 代码遍历 self::cases() 返回的数组,将每个案例的 name 属性与预处理后的输入字符串进行严格比较(===)。
  5. 返回结果: 如果找到匹配项,则返回对应的枚举案例;如果遍历完所有案例仍未找到,则返回 null。

3. 注意事项与总结

  • 选择合适的枚举类型: 如果你的枚举案例需要关联一个唯一的、可用于查找的字符串或整数值,优先考虑使用 Backed Enum。这将允许你利用原生的 tryFrom() 方法,代码更简洁且性能更优。
  • 纯枚举的灵活性: 纯枚举适用于只需要一组命名常量,而无需额外底层值的情况。当需要根据字符串名称获取纯枚举案例时,自定义的静态 get() 方法是最佳实践。
  • 错误处理:
    • 对于 BackedEnum::from(),如果匹配失败会抛出 ValueError,因此在使用时应考虑 try-catch 块。
    • BackedEnum::tryFrom() 和自定义的 get() 方法在匹配失败时返回 null,这使得错误处理更加平滑,你可以通过检查返回值是否为 null 来判断是否成功获取到案例。
  • 性能考量: 自定义的 get() 方法涉及遍历所有枚举案例。对于拥有大量案例的枚举,这可能会有轻微的性能开销,但对于大多数实际应用场景,这种开销通常可以忽略不计。如果性能成为瓶颈,可以考虑在 get() 方法内部维护一个静态缓存映射(例如 ['OK' => Status::OK, ...]),但通常不必要。

通过理解 Backed Enums 的原生 tryFrom() 方法和为纯枚举实现自定义 get() 方法,你可以在 PHP 中灵活高效地根据字符串值获取所需的枚举案例,从而提高代码的可读性和健壮性。

以上就是PHP 枚举:根据字符串获取枚举案例的策略与实现的详细内容,更多请关注php中文网其它相关文章!


# 它将  # 石排镇网站优化  # 滁州网站建设优点缺点  # 齐全的泉州seo咨询  # 佛山校园关键词排名如何  # 极度信息网站建设流程  # 传媒资讯类网站建设要求  # 麻涌网站关键词排名  # 河南seo查询平台公司  # 电工电气网站优化查询  # 护肤品牌做推广营销  # php  # 转换为  # 怎么看  # 找不到  # 你可以  # 字符串值  # 都有  # 抛出  # 遍历  # 自定义  # ai 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 智云Q3和Q2有什么升级_智云Q3与Q2手持云台功能与性能对比分析  如何自定义苹果手机铃声  mysql如何配置从库只读_mysql从库只读设置方法  《随手记》启用语音备注方法  如何编写一个符合 composer 规范的 post-install-cmd 脚本?  PSD转AI文件的简单方法  Excel如何快速找到并断开外部数据源链接_Excel外部数据源断开方法  风神瞳获取全攻略  《大周列国志》皇帝律令功能介绍  背部总是隐隐作痛怎么回事 背痛如何改善  如何解决Casbin日志与应用日志不统一的问题,使用casbin/psr3-bridge实现无缝集成  疯狂小鸟微信小游戏入口 疯狂小鸟网页版秒玩  t3出行如何使用微信支付  《随手记》备份数据方法  被称为海蜈蚣的海洋动物是  php如何实现多域名共享session_php存储session到redis与跨域读取配置  小米手机屏幕失灵乱跳怎么办 屏幕触控问题自检与临时解决方法【应急】  C++ virtual析构函数作用_C++基类虚析构函数防止内存泄漏  济南公交卡手机充值指南  AngularJS动态内容中DOM元素查找的时序问题及$timeout解决方案  如何测试您的网站全球打开速度-网站海外测速工  mysql如何回滚事务_mysql ROLLBACK事务回滚方法  HTML Canvas文本样式定制指南:解决外部字体加载与应用难题  如何用mysql实现客户反馈管理_mysql客户反馈数据库方法  教资成绩怎么查询  Windows Audio服务启动失败怎么办_电脑没声音的终极服务修复法【修复】  Python中处理嵌套字典与列表的数据提取与过滤教程  国际经济与贸易就业方向解析  PHP页面重载时变量值不重置的实现方法  免费占卜在线神算_免费占卜手机神算  yy漫画官方网站登录入口_yy漫画在线阅读页面地址  《爱笔思画x》魔棒工具抠图教程  感染了幽门螺杆菌一定会导致胃癌吗?蚂蚁庄园今日答案最新11.30  firefox火狐浏览器最新官网主页_ firefox火狐浏览器平台入口直达官方链接  抖音如何解除|直播|权限绑定_抖音关闭并解绑|直播|功能的方法  《深林》冬季章节图文攻略  2025考研成绩查询时间入口分享  TikTok视频播放中断怎么办 TikTok播放异常修复方法  《我的恋爱逃生攻略》中文名字输入方法  键盘保修需要什么_键盘售后维修流程  PHP动态导航按钮:根据用户登录状态切换链接与文本  《洛克王国:世界》国家队搭配攻略  百度识图图像分析 百度识图识别平台  《小宇宙》标记不友善评论方法  Windows自带的便笺数据如何备份_防止数据丢失的便利贴迁移教程【干货】  蛙漫2(台版)正版官网 2025免费网页版分享  解决Go encoding/json 将JSON大数字解析为浮点数的问题  店铺如何做视频号推广?做视频号推广有用吗?  J*a中导出MySQL表为SQL脚本的两种方法  抖音火山版如何进行提现 

 2025-12-01

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.