composer  require  myclabs/php-enum
<?php
require_once 'vendor/autoload.php';

use MyCLabs\Enum\Enum;

echo "=== PHP Enum 示例 ===\n\n";

// ============================================
// 示例1: 基本枚举 - 订单状态
// ============================================
echo "--- 示例1: 订单状态枚举 ---\n";

/**
 * 订单状态枚举
 * @method static OrderStatus PENDING()
 * @method static OrderStatus PAID()
 * @method static OrderStatus SHIPPED()
 * @method static OrderStatus DELIVERED()
 * @method static OrderStatus CANCELLED()
 */
class OrderStatus extends Enum
{
    private const PENDING = 'pending';      // 待支付
    private const PAID = 'paid';           // 已支付
    private const SHIPPED = 'shipped';     // 已发货
    private const DELIVERED = 'delivered'; // 已送达
    private const CANCELLED = 'cancelled'; // 已取消
}

// 创建枚举实例
$status1 = OrderStatus::PENDING();
$status2 = OrderStatus::PAID();

echo "订单状态1: {$status1->getValue()}\n";
echo "订单状态2: {$status2->getValue()}\n";

// 比较枚举
if ($status1->equals(OrderStatus::PENDING())) {
    echo "订单状态1 是待支付状态\n";
}

if (!$status1->equals($status2)) {
    echo "两个订单状态不同\n";
}
echo "\n";

// ============================================
// 示例2: 使用枚举作为函数参数(类型安全)
// ============================================
echo "--- 示例2: 类型安全的函数参数 ---\n";

function processOrder(OrderStatus $status) {
    switch ($status->getValue()) {
        case 'pending':
            return "等待用户支付...";
        case 'paid':
            return "订单已支付,准备发货";
        case 'shipped':
            return "订单已发货,运输中";
        case 'delivered':
            return "订单已送达";
        case 'cancelled':
            return "订单已取消";
        default:
            return "未知状态";
    }
}

echo processOrder(OrderStatus::PAID()) . "\n";
echo processOrder(OrderStatus::SHIPPED()) . "\n";
echo "\n";

// ============================================
// 示例3: 获取所有枚举值
// ============================================
echo "--- 示例3: 获取所有枚举值 ---\n";

echo "所有订单状态:\n";
foreach (OrderStatus::values() as $status) {
    echo "  - {$status->getValue()}\n";
}
echo "\n";

// 获取所有 key
echo "所有订单状态 Key:\n";
foreach (OrderStatus::keys() as $key) {
    echo "  - {$key}\n";
}
echo "\n";

// ============================================
// 示例4: 从值创建枚举实例
// ============================================
echo "--- 示例4: 从字符串创建枚举 ---\n";

try {
    // 从数据库或用户输入获取的值
    $statusFromDB = 'paid';
    $status = new OrderStatus($statusFromDB);
    echo "从值 '{$statusFromDB}' 创建的状态: {$status->getValue()}\n";
    echo "Key: {$status->getKey()}\n";
} catch (\UnexpectedValueException $e) {
    echo "错误: 无效的状态值\n";
}

// 验证值是否有效
echo "\n验证状态值:\n";
echo "  'paid' 是否有效: " . (OrderStatus::isValid('paid') ? '是' : '否') . "\n";
echo "  'invalid' 是否有效: " . (OrderStatus::isValid('invalid') ? '是' : '否') . "\n";
echo "\n";

// ============================================
// 示例5: 用户角色枚举(带描述)
// ============================================
echo "--- 示例5: 带描述的枚举 ---\n";

/**
 * 用户角色枚举
 * @method static UserRole ADMIN()
 * @method static UserRole EDITOR()
 * @method static UserRole VIEWER()
 * @method static UserRole GUEST()
 */
class UserRole extends Enum
{
    private const ADMIN = 'admin';
    private const EDITOR = 'editor';
    private const VIEWER = 'viewer';
    private const GUEST = 'guest';

    // 自定义方法:获取角色描述
    public function getDescription(): string
    {
        $descriptions = [
            self::ADMIN => '管理员 - 拥有所有权限',
            self::EDITOR => '编辑者 - 可以编辑内容',
            self::VIEWER => '查看者 - 只能查看内容',
            self::GUEST => '访客 - 受限访问',
        ];

        return $descriptions[$this->getValue()] ?? '未知角色';
    }

    // 自定义方法:检查权限
    public function canEdit(): bool
    {
        return in_array($this->getValue(), [self::ADMIN, self::EDITOR]);
    }

    public function canDelete(): bool
    {
        return $this->getValue() === self::ADMIN;
    }
}

$adminRole = UserRole::ADMIN();
$viewerRole = UserRole::VIEWER();

echo "角色: {$adminRole->getKey()}\n";
echo "描述: {$adminRole->getDescription()}\n";
echo "可以编辑: " . ($adminRole->canEdit() ? '是' : '否') . "\n";
echo "可以删除: " . ($adminRole->canDelete() ? '是' : '否') . "\n\n";

echo "角色: {$viewerRole->getKey()}\n";
echo "描述: {$viewerRole->getDescription()}\n";
echo "可以编辑: " . ($viewerRole->canEdit() ? '是' : '否') . "\n";
echo "可以删除: " . ($viewerRole->canDelete() ? '是' : '否') . "\n\n";

// ============================================
// 示例6: HTTP 方法枚举
// ============================================
echo "--- 示例6: HTTP 方法枚举 ---\n";

/**
 * @method static HttpMethod GET()
 * @method static HttpMethod POST()
 * @method static HttpMethod PUT()
 * @method static HttpMethod DELETE()
 * @method static HttpMethod PATCH()
 */
class HttpMethod extends Enum
{
    private const GET = 'GET';
    private const POST = 'POST';
    private const PUT = 'PUT';
    private const DELETE = 'DELETE';
    private const PATCH = 'PATCH';
}

function makeRequest(string $url, HttpMethod $method, array $data = []) {
    return "发送 {$method->getValue()} 请求到 {$url}" .
           (empty($data) ? '' : ' 携带数据: ' . json_encode($data));
}

echo makeRequest('/api/users', HttpMethod::GET()) . "\n";
echo makeRequest('/api/users', HttpMethod::POST(), ['name' => '张三']) . "\n";
echo makeRequest('/api/users/1', HttpMethod::DELETE()) . "\n";
echo "\n";

// ============================================
// 示例7: 日志级别枚举
// ============================================
echo "--- 示例7: 日志级别枚举 ---\n";

/**
 * @method static LogLevel DEBUG()
 * @method static LogLevel INFO()
 * @method static LogLevel WARNING()
 * @method static LogLevel ERROR()
 * @method static LogLevel CRITICAL()
 */
class LogLevel extends Enum
{
    private const DEBUG = 1;
    private const INFO = 2;
    private const WARNING = 3;
    private const ERROR = 4;
    private const CRITICAL = 5;

    public function isMoreSevereThan(LogLevel $other): bool
    {
        return $this->getValue() > $other->getValue();
    }
}

function writeLog(string $message, LogLevel $level) {
    $minLevel = LogLevel::WARNING(); // 最低记录级别

    if ($level->getValue() >= $minLevel->getValue()) {
        echo "[{$level->getKey()}] {$message}\n";
    }
}

writeLog("调试信息", LogLevel::DEBUG());      // 不会输出(低于 WARNING)
writeLog("普通信息", LogLevel::INFO());       // 不会输出(低于 WARNING)
writeLog("警告信息", LogLevel::WARNING());    // 会输出
writeLog("错误信息", LogLevel::ERROR());      // 会输出
writeLog("严重错误", LogLevel::CRITICAL());   // 会输出

echo "\n";

// ============================================
// 示例8: 实际应用 - 订单处理系统
// ============================================
echo "--- 示例8: 完整的订单处理示例 ---\n";

class Order {
    private $id;
    private $status;
    private $amount;

    public function __construct(int $id, float $amount) {
        $this->id = $id;
        $this->status = OrderStatus::PENDING();
        $this->amount = $amount;
    }

    public function pay(): void {
        if (!$this->status->equals(OrderStatus::PENDING())) {
            throw new Exception("只有待支付订单才能支付");
        }
        $this->status = OrderStatus::PAID();
    }

    public function ship(): void {
        if (!$this->status->equals(OrderStatus::PAID())) {
            throw new Exception("只有已支付订单才能发货");
        }
        $this->status = OrderStatus::SHIPPED();
    }

    public function deliver(): void {
        if (!$this->status->equals(OrderStatus::SHIPPED())) {
            throw new Exception("只有已发货订单才能标记为送达");
        }
        $this->status = OrderStatus::DELIVERED();
    }

    public function cancel(): void {
        if ($this->status->equals(OrderStatus::DELIVERED())) {
            throw new Exception("已送达的订单不能取消");
        }
        $this->status = OrderStatus::CANCELLED();
    }

    public function getStatus(): OrderStatus {
        return $this->status;
    }

    public function getInfo(): string {
        return "订单 #{$this->id} - 金额: ¥{$this->amount} - 状态: {$this->status->getKey()}";
    }
}

// 模拟订单处理流程
$order = new Order(1001, 299.99);
echo $order->getInfo() . "\n";

$order->pay();
echo "支付成功 -> " . $order->getInfo() . "\n";

$order->ship();
echo "发货成功 -> " . $order->getInfo() . "\n";

$order->deliver();
echo "送达成功 -> " . $order->getInfo() . "\n";

echo "\n完成所有示例!\n";

解释

=== PHP Enum 示例 ===

— 示例1: 订单状态枚举 —
订单状态1: pending
订单状态2: paid
订单状态1 是待支付状态
两个订单状态不同

— 示例2: 类型安全的函数参数 —
订单已支付,准备发货
订单已发货,运输中

— 示例3: 获取所有枚举值 —
所有订单状态:

  • pending
  • paid
  • shipped
  • delivered
  • cancelled

所有订单状态 Key:

  • PENDING
  • PAID
  • SHIPPED
  • DELIVERED
  • CANCELLED

— 示例4: 从字符串创建枚举 —
从值 ‘paid’ 创建的状态: paid
Key: PAID

验证状态值:
‘paid’ 是否有效: 是
‘invalid’ 是否有效: 否

— 示例5: 带描述的枚举 —
角色: ADMIN
描述: 管理员 - 拥有所有权限
可以编辑: 是
可以删除: 是

角色: VIEWER
描述: 查看者 - 只能查看内容
可以编辑: 否
可以删除: 否

— 示例6: HTTP 方法枚举 —
发送 GET 请求到 /api/users
发送 POST 请求到 /api/users 携带数据: {“name”:“\u5f20\u4e09”}
发送 DELETE 请求到 /api/users/1

— 示例7: 日志级别枚举 —
[WARNING] 警告信息
[ERROR] 错误信息
[CRITICAL] 严重错误

— 示例8: 完整的订单处理示例 —
订单 #1001 - 金额: ¥299.99 - 状态: PENDING
支付成功 -> 订单 #1001 - 金额: ¥299.99 - 状态: PAID
发货成功 -> 订单 #1001 - 金额: ¥299.99 - 状态: SHIPPED
送达成功 -> 订单 #1001 - 金额: ¥299.99 - 状态: DELIVERED

完成所有示例!

解释

什么是枚举

枚举(Enum) 是一种特殊的数据类型,用于定义一组固定的常量值。

简单理解:

  • 就像一个"选择题",只能从预定义的选项中选择
  • 例如:订单状态只能是"待支付"、“已支付”、"已发货"等,不能是其他值

传统方式 vs 枚举方式:

// 传统方式(不安全,容易出错)
$status = 'paid';  // 可能拼写错误:'piad', 'Pay', 'PAID'

// 枚举方式(类型安全)
$status = OrderStatus::PAID();  // IDE 自动补全,不会拼写错误

为什么使用枚举

问题场景

// 不使用枚举的代码(问题多多)
function processOrder($status) {
    if ($status == 'paid') {  // 拼写错误:'piad'
        // ...
    }
}

processOrder('piad');  // 不会报错,但逻辑错误!
processOrder('随便什么值');  // 也不会报错

使用枚举的好处

// 使用枚举(类型安全)
function processOrder(OrderStatus $status) {  // 强制类型
    if ($status->equals(OrderStatus::PAID())) {
        // ...
    }
}

processOrder(OrderStatus::PAID());  // ✅ 正确
processOrder('paid');  // ❌ 报错:类型不匹配

优点总结:

  1. 类型安全 - 防止拼写错误和无效值
  2. 代码清晰 - 一眼看出所有可能的值
  3. IDE 支持 - 自动补全、跳转定义
  4. 易于维护 - 修改值只需改一个地方
  5. 可扩展 - 可以添加自定义方法

基本概念

1. 定义枚举类

/**
 * @method static OrderStatus PENDING()   // 魔术注释,用于 IDE 提示
 * @method static OrderStatus PAID()
 */
class OrderStatus extends Enum  // 继承 Enum 类
{
    private const PENDING = 'pending';  // 定义常量(值)
    private const PAID = 'paid';
}

解释:

  • extends Enum - 继承枚举基类,获得枚举功能
  • private const - 私有常量,外部不能直接访问
  • @method static - PHPDoc 注释,告诉 IDE 有这些静态方法

2. 创建枚举实例

// 方法1:静态调用(推荐)
$status = OrderStatus::PENDING();

// 方法2:从值创建
$status = new OrderStatus('pending');

3. 获取枚举的值和键

$status = OrderStatus::PAID();

echo $status->getValue();  // 输出:'paid'(值)
echo $status->getKey();    // 输出:'PAID'(常量名)

详细示例解释

示例1: 订单状态枚举(基础)

class OrderStatus extends Enum
{
    private const PENDING = 'pending';      // 待支付
    private const PAID = 'paid';           // 已支付
    private const SHIPPED = 'shipped';     // 已发货
    private const DELIVERED = 'delivered'; // 已送达
    private const CANCELLED = 'cancelled'; // 已取消
}

用途: 表示订单的所有可能状态

使用:

$status1 = OrderStatus::PENDING();  // 创建"待支付"状态
$status2 = OrderStatus::PAID();     // 创建"已支付"状态

// 比较两个枚举
if ($status1->equals(OrderStatus::PENDING())) {
    echo "是待支付状态";  // ✅ 会输出
}

if ($status1->equals($status2)) {
    echo "两个状态相同";  // ❌ 不会输出(状态不同)
}

示例2: 类型安全的函数参数

function processOrder(OrderStatus $status) {  // 参数类型限制
    switch ($status->getValue()) {
        case 'pending':
            return "等待用户支付...";
        case 'paid':
            return "订单已支付,准备发货";
        // ...
    }
}

// 调用
echo processOrder(OrderStatus::PAID());  // ✅ 正确
echo processOrder('paid');  // ❌ 错误:类型不匹配

关键点:

  • OrderStatus $status - 参数类型声明,只接受 OrderStatus 枚举
  • 防止传入错误的字符串或其他类型
  • switch ($status->getValue()) - 获取枚举的实际值进行比较

示例3: 获取所有枚举值

// 获取所有枚举实例
foreach (OrderStatus::values() as $status) {
    echo $status->getValue();  // pending, paid, shipped, delivered, cancelled
}

// 获取所有常量名
foreach (OrderStatus::keys() as $key) {
    echo $key;  // PENDING, PAID, SHIPPED, DELIVERED, CANCELLED
}

用途:

  • 生成下拉选择框
  • 显示所有可选状态
  • 数据验证

实际应用:

// 在表单中生成选择框
echo '<select name="status">';
foreach (OrderStatus::values() as $status) {
    echo '<option value="' . $status->getValue() . '">';
    echo $status->getKey();
    echo '</option>';
}
echo '</select>';

示例4: 从字符串创建枚举

// 从数据库读取的字符串
$statusFromDB = 'paid';

// 转换为枚举对象
$status = new OrderStatus($statusFromDB);

echo $status->getValue();  // 'paid'
echo $status->getKey();    // 'PAID'

验证值是否有效:

if (OrderStatus::isValid('paid')) {
    echo "'paid' 是有效的状态";  // ✅ 输出
}

if (OrderStatus::isValid('invalid')) {
    echo "'invalid' 是有效的状态";  // ❌ 不输出
}

异常处理:

try {
    $status = new OrderStatus('invalid_status');  // 无效值
} catch (\UnexpectedValueException $e) {
    echo "错误:状态值无效";  // 会捕获异常
}

示例5: 带自定义方法的枚举

class UserRole extends Enum
{
    private const ADMIN = 'admin';
    private const EDITOR = 'editor';
    private const VIEWER = 'viewer';
    private const GUEST = 'guest';

    // 自定义方法1:获取描述
    public function getDescription(): string
    {
        $descriptions = [
            self::ADMIN => '管理员 - 拥有所有权限',
            self::EDITOR => '编辑者 - 可以编辑内容',
            self::VIEWER => '查看者 - 只能查看内容',
            self::GUEST => '访客 - 受限访问',
        ];
        return $descriptions[$this->getValue()] ?? '未知角色';
    }

    // 自定义方法2:检查权限
    public function canEdit(): bool
    {
        return in_array($this->getValue(), [self::ADMIN, self::EDITOR]);
    }

    public function canDelete(): bool
    {
        return $this->getValue() === self::ADMIN;
    }
}

使用:

$adminRole = UserRole::ADMIN();

echo $adminRole->getDescription();  // '管理员 - 拥有所有权限'
echo $adminRole->canEdit() ? '可以编辑' : '不能编辑';  // '可以编辑'
echo $adminRole->canDelete() ? '可以删除' : '不能删除';  // '可以删除'

$viewerRole = UserRole::VIEWER();
echo $viewerRole->canEdit() ? '可以编辑' : '不能编辑';  // '不能编辑'

为什么有用:

  • 将业务逻辑封装在枚举类中
  • 代码更清晰,权限判断统一管理
  • 修改权限规则只需改一个地方

示例6: HTTP 方法枚举

class HttpMethod extends Enum
{
    private const GET = 'GET';
    private const POST = 'POST';
    private const PUT = 'PUT';
    private const DELETE = 'DELETE';
    private const PATCH = 'PATCH';
}

function makeRequest(string $url, HttpMethod $method, array $data = []) {
    return "发送 {$method->getValue()} 请求到 {$url}";
}

// 使用
echo makeRequest('/api/users', HttpMethod::GET());
echo makeRequest('/api/users', HttpMethod::POST(), ['name' => '张三']);

应用场景:

  • API 客户端
  • HTTP 请求封装
  • RESTful 路由

示例7: 日志级别枚举(数字值)

class LogLevel extends Enum
{
    private const DEBUG = 1;       // 最低级别
    private const INFO = 2;
    private const WARNING = 3;
    private const ERROR = 4;
    private const CRITICAL = 5;    // 最高级别

    // 自定义方法:比较严重程度
    public function isMoreSevereThan(LogLevel $other): bool
    {
        return $this->getValue() > $other->getValue();
    }
}

使用:

function writeLog(string $message, LogLevel $level) {
    $minLevel = LogLevel::WARNING();  // 最低记录级别

    if ($level->getValue() >= $minLevel->getValue()) {
        echo "[{$level->getKey()}] {$message}\n";
    }
}

writeLog("调试信息", LogLevel::DEBUG());    // 不输出(级别太低)
writeLog("警告信息", LogLevel::WARNING());  // 输出:[WARNING] 警告信息
writeLog("错误信息", LogLevel::ERROR());    // 输出:[ERROR] 错误信息

关键点:

  • 枚举值可以是数字
  • 可以进行数值比较
  • 适合有优先级/等级的场景

示例8: 完整的订单处理系统

class Order {
    private $id;
    private $status;
    private $amount;

    public function __construct(int $id, float $amount) {
        $this->id = $id;
        $this->status = OrderStatus::PENDING();  // 初始状态:待支付
        $this->amount = $amount;
    }

    // 支付
    public function pay(): void {
        if (!$this->status->equals(OrderStatus::PENDING())) {
            throw new Exception("只有待支付订单才能支付");
        }
        $this->status = OrderStatus::PAID();
    }

    // 发货
    public function ship(): void {
        if (!$this->status->equals(OrderStatus::PAID())) {
            throw new Exception("只有已支付订单才能发货");
        }
        $this->status = OrderStatus::SHIPPED();
    }

    // 送达
    public function deliver(): void {
        if (!$this->status->equals(OrderStatus::SHIPPED())) {
            throw new Exception("只有已发货订单才能标记为送达");
        }
        $this->status = OrderStatus::DELIVERED();
    }

    public function getInfo(): string {
        return "订单 #{$this->id} - 金额: ¥{$this->amount} - 状态: {$this->status->getKey()}";
    }
}

使用流程:

$order = new Order(1001, 299.99);
echo $order->getInfo();  // 订单 #1001 - 金额: ¥299.99 - 状态: PENDING

$order->pay();
echo $order->getInfo();  // 订单 #1001 - 金额: ¥299.99 - 状态: PAID

$order->ship();
echo $order->getInfo();  // 订单 #1001 - 金额: ¥299.99 - 状态: SHIPPED

$order->deliver();
echo $order->getInfo();  // 订单 #1001 - 金额: ¥299.99 - 状态: DELIVERED

状态流转控制:

$order = new Order(1001, 299.99);

// 尝试直接发货(会报错)
try {
    $order->ship();  // ❌ 报错:只有已支付订单才能发货
} catch (Exception $e) {
    echo $e->getMessage();
}

// 正确流程
$order->pay();    // ✅ 先支付
$order->ship();   // ✅ 再发货

常用方法

Enum 基类提供的方法

方法 说明 示例
getValue() 获取枚举的值 $status->getValue()'paid'
getKey() 获取枚举的常量名 $status->getKey()'PAID'
equals($other) 比较两个枚举是否相等 $status->equals(OrderStatus::PAID())
__toString() 转为字符串(自动调用 getValue) echo $status'paid'
static values() 获取所有枚举实例 OrderStatus::values()
static keys() 获取所有常量名 OrderStatus::keys()
static isValid($value) 检查值是否有效 OrderStatus::isValid('paid')
static toArray() 转为关联数组 OrderStatus::toArray()['PENDING' => 'pending', ...]

实际应用场景

1. 电商系统

// 订单状态
class OrderStatus extends Enum {
    private const PENDING = 'pending';
    private const PAID = 'paid';
    private const SHIPPED = 'shipped';
    // ...
}

// 支付方式
class PaymentMethod extends Enum {
    private const ALIPAY = 'alipay';
    private const WECHAT = 'wechat';
    private const CREDIT_CARD = 'credit_card';
}

// 物流状态
class ShippingStatus extends Enum {
    private const PENDING = 'pending';
    private const IN_TRANSIT = 'in_transit';
    private const DELIVERED = 'delivered';
}

2. 用户系统

// 用户角色
class UserRole extends Enum {
    private const ADMIN = 'admin';
    private const MODERATOR = 'moderator';
    private const USER = 'user';
}

// 账号状态
class AccountStatus extends Enum {
    private const ACTIVE = 'active';
    private const SUSPENDED = 'suspended';
    private const BANNED = 'banned';
}

3. 内容管理

// 文章状态
class ArticleStatus extends Enum {
    private const DRAFT = 'draft';
    private const PUBLISHED = 'published';
    private const ARCHIVED = 'archived';
}

// 评论状态
class CommentStatus extends Enum {
    private const PENDING = 'pending';
    private const APPROVED = 'approved';
    private const SPAM = 'spam';
}

4. API 开发

// HTTP 状态码
class HttpStatus extends Enum {
    private const OK = 200;
    private const CREATED = 201;
    private const BAD_REQUEST = 400;
    private const UNAUTHORIZED = 401;
    private const NOT_FOUND = 404;
    private const SERVER_ERROR = 500;
}

// API 响应类型
class ResponseType extends Enum {
    private const JSON = 'json';
    private const XML = 'xml';
    private const HTML = 'html';
}

总结

何时使用枚举?

✅ 适合使用枚举:

  • 有固定的、有限的选项(如状态、类型、级别)
  • 需要类型安全的场景
  • 需要在代码中多处使用同一组常量
  • 需要附加业务逻辑(如权限检查)

❌ 不适合使用枚举:

  • 值是动态的、从数据库读取的
  • 选项数量非常多(几百上千个)
  • 简单的布尔值场景(直接用 true/false)

最佳实践

  1. 命名规范

    • 枚举类名:大驼峰(OrderStatus, UserRole)
    • 常量名:全大写下划线(PENDING, PAID)
    • 值:小写下划线(‘pending’, ‘paid’)
  2. 添加注释

    • 为每个常量添加中文注释
    • 添加 @method 注释提示 IDE
  3. 验证输入

    • 使用 isValid() 验证用户输入
    • 使用 try-catch 捕获无效值异常
  4. 类型提示

    • 函数参数使用枚举类型提示
    • 类属性声明枚举类型

常见问题

Q1: 如何在数据库中存储枚举?

// 存储:保存枚举的值(字符串或数字)
$db->insert('orders', [
    'status' => $order->getStatus()->getValue()  // 'paid'
]);

// 读取:从值创建枚举
$statusFromDB = $db->query('SELECT status FROM orders WHERE id = 1');
$status = new OrderStatus($statusFromDB['status']);

Q2: 如何在 JSON API 中使用枚举?

class Order {
    public function toArray(): array {
        return [
            'id' => $this->id,
            'status' => $this->status->getValue(),  // 转为字符串
            'status_key' => $this->status->getKey(),
        ];
    }
}

echo json_encode($order->toArray());
// {"id":1001,"status":"paid","status_key":"PAID"}

Q3: PHP 8.1 原生枚举 vs myclabs/php-enum?

  • PHP 8.1+:推荐使用原生 enum 关键字(性能更好)
  • PHP 7.x:使用 myclabs/php-enum
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐