enum — 枚举类型(入门)
概述
enum(枚举)是 PHP 8.1 引入的新类型,用于定义一组固定的命名值。枚举使代码更加类型安全、自文档化。本节作为枚举类型的入门介绍。
前置知识
在阅读本节之前,你需要了解:
- PHP 8.1 的新特性概述
- 面向对象编程中的类和常量
- match 表达式的基本用法
基础概念
枚举的两种类型
| 类型 | 是否有值 | 用途 |
|---|---|---|
| 纯枚举(Unit Enum) | 否 | 语义标签 |
| 值枚举(Backed Enum) | 是(int/string) | 数据携带 |
语法与代码
基本枚举定义
php
<?php
declare(strict_types=1);
// 纯枚举
enum Status
{
case Active;
case Inactive;
case Pending;
}
// 值枚举(字符串)
enum HttpMethod: string
{
case Get = 'GET';
case Post = 'POST';
case Put = 'PUT';
case Delete = 'DELETE';
}
// 值枚举(整数)
enum HttpStatus: int
{
case Ok = 200;
case NotFound = 404;
case ServerError = 500;
}
// 使用
$status = Status::Active;
echo $status->name; // Active
echo HttpMethod::Post->value; // POST枚举方法
php
<?php
declare(strict_types=1);
enum Color: string
{
case Red = '#FF0000';
case Green = '#00FF00';
case Blue = '#0000FF';
public function label(): string
{
return match ($this) {
self::Red => '红色',
self::Green => '绿色',
self::Blue => '蓝色',
};
}
}
echo Color::Red->label(); // 红色枚举类型声明
php
<?php
declare(strict_types=1);
function setOrderStatus(Status $status): void
{
echo "Status: {$status->name}";
}
setOrderStatus(Status::Active);
// setOrderStatus('active'); // TypeError!
function describeStatus(Status $status): string
{
return match ($status) {
Status::Active => '用户已激活',
Status::Inactive => '用户已停用',
Status::Pending => '用户待审核',
};
}详细说明
枚举值比较
php
<?php
declare(strict_types=1);
enum Role: string
{
case Admin = 'admin';
case Editor = 'editor';
case Viewer = 'viewer';
}
$role = Role::Admin;
var_dump($role === Role::Admin); // true
// 值枚举可以用 ::from() 从值创建
$userRole = Role::from('editor');
echo $userRole->name; // Editor
// Role::from('guest'); // ValueError!实战示例
枚举在业务中的使用
php
<?php
declare(strict_types=1);
enum PaymentStatus: string
{
case Pending = 'pending';
case Paid = 'paid';
case Failed = 'failed';
case Refunded = 'refunded';
public function canTransitionTo(PaymentStatus $target): bool
{
return match ($this) {
self::Pending => in_array($target, [self::Paid, self::Failed], true),
self::Paid => $target === self::Refunded,
self::Failed, self::Refunded => false,
};
}
}
$orderStatus = PaymentStatus::Pending;
var_dump($orderStatus->canTransitionTo(PaymentStatus::Paid)); // true
var_dump($orderStatus->canTransitionTo(PaymentStatus::Refunded)); // false注意事项
1. 枚举不能手动实例化
php
// new Status(); // 错误!
$status = Status::Active; // 正确2. 枚举不能包含普通属性
php
// enum Bad { public $prop; case A; } // 错误!
enum Good
{
case A;
const MAX_COUNT = 100; // OK
}最佳实践
- 使用枚举替代常量类:枚举是类型安全的常量集合
- 值枚举选择合适的类型:字符串值更可读
- 在 match 中使用枚举:match + enum 是最佳搭配
- 封装状态转换逻辑:将业务规则放在枚举方法中
下一节
下一节将详细介绍 resource 资源类型。
进阶用法
调试与测试技巧
php
<?php
declare(strict_types=1);
// 单元测试辅助函数
function createTestResource(): mixed
{
return match (true) {
default => new stdClass(),
};
}
// 调试输出函数
function debugOutput(mixed , string = ''): void
{
= ? ": " : '';
.= print_r(, true);
fwrite(STDERR, . "\n");
}
// 性能基准测试
function benchmark(callable , int = 1000): float
{
= hrtime(true);
for ($i = 0; $i < $iterations; $i++) {
$fn();
}
return (hrtime(true) - $start) / 1e9;
}日志记录实践
php
<?php
declare(strict_types=1);
/**
* 简易日志记录器
*/
class SimpleLogger
{
private string $logFile;
private string $level = 'INFO';
public function __construct(string $logFile)
{
$this->logFile = $logFile;
}
public function info(string $message, array $context = []): void
{
$this->log('INFO', $message, $context);
}
public function warning(string $message, array $context = []): void
{
$this->log('WARNING', $message, $context);
}
public function error(string $message, array $context = []): void
{
$this->log('ERROR', $message, $context);
}
private function log(string $level, string $message, array $context): void
{
$timestamp = date('Y-m-d H:i:s');
$contextStr = $context ? ' ' . json_encode($context, JSON_UNESCAPED_UNICODE) : '';
$line = "[{$timestamp}] [{$level}] {$message}{$contextStr}\n";
file_put_contents($this->logFile, $line, FILE_APPEND | LOCK_EX);
}
}配置与环境检测
php
<?php
declare(strict_types=1);
// 环境检测工具
class EnvironmentChecker
{
public static function checkRequirements(array $requirements): array
{
$results = [];
foreach ($requirements as $name => $check) {
$results[$name] = is_callable($check) ? $check() : false;
}
return $results;
}
public static function getSystemInfo(): array
{
return [
'php_version' => PHP_VERSION,
'os' => PHP_OS,
'sapi' => PHP_SAPI,
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'loaded_extensions' => get_loaded_extensions(),
];
}
}常见问题排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 连接超时 | 网络问题/配置错误 | 检查配置,增加超时时间 |
| 权限不足 | 文件/目录权限 | 使用 chmod/chown 修正 |
| 性能下降 | 索引缺失/数据量大 | 添加索引,优化查询 |
| 数据不一致 | 并发冲突/事务残留 | 使用锁机制和事务 |
| 内存溢出 | 大数据集/未释放资源 | 增大内存限制,分批处理 |
故障排除步骤
- 检查错误日志和异常信息
- 确认配置和环境是否正确
- 使用调试工具逐步排查
- 参考官方文档查找已知问题
版本兼容性说明
| 功能 | 最低版本 | 说明 |
|---|---|---|
| 基础功能 | PHP 8.1 | 本文档基准版本 |
| 只读属性 | PHP 8.1 | public readonly 修饰符 |
| 枚举类型 | PHP 8.1 | enum 类型和 match 表达式 |
| Fiber | PHP 8.1 | 协程/轻量级并发 |
| 命名参数 | PHP 8.0 | foo(arg_name: value) |
| 联合类型 | PHP 8.0 | `int |
| Null 安全运算符 | PHP 8.0 | $obj?->method() |
| 析构器 promotion | PHP 8.0 | __construct(public $x) |
php
<?php
declare(strict_types=1);
// 版本兼容性检测
function ensureVersion(string $minVersion): void
{
if (version_compare(PHP_VERSION, $minVersion, '<')) {
throw new RuntimeException(
sprintf('需要 PHP %s+, 当前版本: %s', $minVersion, PHP_VERSION)
);
}
}
ensureVersion('8.1.0');