PHP枚举验证支持类型吗

wen PHP项目 2

本文目录导读:

PHP枚举验证支持类型吗

  1. 基础枚举验证
  2. 回退枚举(Backed Enum)
  3. 类型验证场景
  4. 高级类型验证模式
  5. JSON 序列化验证
  6. 框架集成示例(Laravel)

是的,PHP 8.1+ 正式支持枚举(Enum),并且枚举验证也支持多种类型,以下是详细说明:

基础枚举验证

纯枚举类型

enum Status {
    case Pending;
    case Approved;
    case Rejected;
}
function processStatus(Status $status): void {
    // 类型安全验证
    match($status) {
        Status::Pending => echo "等待处理",
        Status::Approved => echo "已批准",
        Status::Rejected => echo "已拒绝",
    };
}
// 调用
processStatus(Status::Pending); // 正确
// processStatus('Pending'); // 类型错误,会抛出 TypeError

回退枚举(Backed Enum)

字符串回退

enum OrderStatus: string {
    case Pending = 'pending';
    case Approved = 'approved';
    case Cancelled = 'cancelled';
}
// 验证字符串值
function validateStatus(string $value): ?OrderStatus {
    return OrderStatus::tryFrom($value);
}
// 使用 tryFrom 进行安全转换
$status = OrderStatus::tryFrom('pending'); // OrderStatus::Pending
$invalid = OrderStatus::tryFrom('unknown'); // null

整数回退

enum HttpStatus: int {
    case OK = 200;
    case NotFound = 404;
    case ServerError = 500;
}
function getHttpStatus(int $code): HttpStatus {
    return HttpStatus::from($code); // 会抛出 ValueError 如果无效
}
// tryFrom 安全版本
function safeGetStatus(int $code): ?HttpStatus {
    return HttpStatus::tryFrom($code);
}

类型验证场景

表单验证示例

enum UserRole: string {
    case Admin = 'admin';
    case Editor = 'editor';
    case Viewer = 'viewer';
    public static function validValues(): array {
        return array_column(self::cases(), 'value');
    }
}
// 表单验证
function validateRole(string $role): bool {
    return in_array($role, UserRole::validValues());
}
// 或使用直接转换
function processForm(array $data): void {
    $role = UserRole::tryFrom($data['role'] ?? '');
    if ($role === null) {
        throw new InvalidArgumentException('无效的用户角色');
    }
    // 处理有效角色
    echo $role->value; // admin, editor, viewer
}

高级类型验证模式

带方法的枚举验证

enum PaymentMethod: string {
    case CreditCard = 'credit_card';
    case PayPal = 'paypal';
    case BankTransfer = 'bank_transfer';
    public static function validate(string $method): bool {
        return !is_null(self::tryFrom($method));
    }
    public static function isValidForRegion(string $method, string $region): bool {
        $enum = self::tryFrom($method);
        if (!$enum) {
            return false;
        }
        return match($enum) {
            self::PayPal => in_array($region, ['US', 'EU']),
            self::BankTransfer => true,
            default => true,
        };
    }
}
// 使用
if (PaymentMethod::validate('paypal')) {
    echo "有效的支付方式";
}

多个值验证

enum Permission: int {
    case Read = 1;
    case Write = 2;
    case Execute = 4;
    case Delete = 8;
    public static function fromBitmask(int $mask): array {
        $permissions = [];
        foreach (self::cases() as $permission) {
            if ($mask & $permission->value) {
                $permissions[] = $permission;
            }
        }
        return $permissions;
    }
}
// 验证权限位掩码
$userPermissions = Permission::fromBitmask(7); // [Read, Write, Execute]

JSON 序列化验证

enum ApiVersion: string {
    case V1 = '1.0';
    case V2 = '2.0';
    case V3 = '3.0';
    public static function fromRequest(string $version): self {
        $normalized = match(true) {
            str_starts_with($version, 'v1') => '1.0',
            str_starts_with($version, 'v2') => '2.0',
            str_starts_with($version, 'v3') => '3.0',
            default => throw new InvalidArgumentException('不支持的 API 版本'),
        };
        return self::from($normalized);
    }
}
// JSON 输入验证
$json = '{"version": "v2", "data": {...}}';
$input = json_decode($json, true);
$version = ApiVersion::fromRequest($input['version']);

框架集成示例(Laravel)

// 自定义验证规则
use Illuminate\Validation\Rule;
$rules = [
    'status' => ['required', Rule::enum(OrderStatus::class)],
    'role' => ['required', Rule::in(UserRole::validValues())],
];
// 或使用类型绑定
Route::get('/users/{role}', function (UserRole $role) {
    return "角色: " . $role->value;
});

PHP 8.1+ 的枚举提供了完善的类型验证支持:

  • 编译时类型检查:参数类型声明
  • 运行时验证tryFrom() 方法
  • 自定义验证逻辑:枚举方法
  • 多种回退类型:string、int
  • 框架集成:Laravel 等框架原生支持

建议在需要固定值集合验证的场景优先使用枚举,它能提供更好的类型安全性和代码可读性。

抱歉,评论功能暂时关闭!