讲师中心 微信公众号
AI工具推荐 视频效率加速

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

风强姑娘_7301

风强姑娘_7301

发布时间:2025-12-01 11:50:02

|

477人浏览过

|

来源于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免费学习笔记(深入)”;

<?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"。

btpanel phpsite 宝塔面板PHP网站
btpanel phpsite 宝塔面板PHP网站

宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理

下载

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

解决方案: 由于没有原生方法,我们需要编写一个自定义的静态方法来遍历所有可用的枚举案例,并将其 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速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6119

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1678

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6004

2023.10.24

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1698

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2584

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6004

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

5489

2023.11.24

Linux 新手先学哪些命令
Linux 新手先学哪些命令

Linux新手命令专题汇集终端基础、文件目录操作、文本查看、软件安装和权限管理等入门文章,帮助按实际任务练习常用命令并建立命令行操作习惯。

0

2026.10.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
墨刀帮助中心
墨刀帮助中心

共0课时 | 0人学习

MyEclipse学习中心
MyEclipse学习中心

共0课时 | 0人学习

Apache Subversion 官方手册
Apache Subversion 官方手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn