本文目录导读:

- PHP 8.1+ 原生枚举 (推荐)
- 使用数据库原生 ENUM 类型
- 使用包:Spatie Enum Laravel
- 使用自定义 Model Casts
- 查询构建器中使用枚举
- 表单验证中的枚举支持
- Blade 模板中的渲染
- API 资源中的格式化
- 最佳实践建议
在 Laravel 项目中实现枚举类型的数据库支持,有几种不同的方案,以下是详细的实现方法和最佳实践:
PHP 8.1+ 原生枚举 (推荐)
定义枚举类
<?php
// app/Enums/UserRole.php
namespace App\Enums;
enum UserRole: string
{
case Admin = 'admin';
case User = 'user';
case Guest = 'guest';
// 添加额外方法
public function label(): string
{
return match($this) {
self::Admin => '管理员',
self::User => '普通用户',
self::Guest => '访客',
};
}
// 获取所有值
public static function values(): array
{
return array_column(self::cases(), 'value');
}
}
数据库迁移
<?php
// database/migrations/xxxx_create_users_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use App\Enums\UserRole;
return new class extends Migration
{
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->enum('role', UserRole::values())->default(UserRole::User);
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('users');
}
};
Model 使用
<?php
// app/Models/User.php
namespace App\Models;
use App\Enums\UserRole;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $casts = [
'role' => UserRole::class,
];
// 可选:添加查询作用域
public function scopeAdmins($query)
{
return $query->where('role', UserRole::Admin);
}
}
使用数据库原生 ENUM 类型
仅 MySQL/PostgreSQL 支持的迁移
<?php
// database/migrations/xxxx_create_orders_table.php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
public function up(): void
{
Schema::create('orders', function (Blueprint $table) {
$table->id();
// 原生 ENUM 类型(仅 MySQL)
$table->enum('status', ['pending', 'processing', 'completed', 'cancelled']);
// PostgreSQL 使用的 CHECK 约束
// $table->string('status')->default('pending');
// $table->check("status IN ('pending', 'processing', 'completed', 'cancelled')");
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('orders');
}
};
使用包:Spatie Enum Laravel
安装
composer require spatie/enum-laravel
创建枚举
php artisan make:enum StatusEnum
定义枚举
<?php
// app/Enums/StatusEnum.php
namespace App\Enums;
use Spatie\Enum\Laravel\Enum;
/**
* @method static self pending()
* @method static self processing()
* @method static self completed()
*/
final class StatusEnum extends Enum
{
protected static function values(): array
{
return [
'pending' => 'pending',
'processing' => 'processing',
'completed' => 'completed',
];
}
protected static function labels(): array
{
return [
'pending' => '待处理',
'processing' => '处理中',
'completed' => '已完成',
];
}
}
使用自定义 Model Casts
<?php
// app/Casts/EnumCast.php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use InvalidArgumentException;
class EnumCast implements CastsAttributes
{
protected $enumClass;
public function __construct(string $enumClass)
{
$this->enumClass = $enumClass;
}
public function get($model, string $key, $value, array $attributes)
{
return $this->enumClass::from($value);
}
public function set($model, string $key, $value, array $attributes)
{
if ($value instanceof $this->enumClass) {
return $value->value;
}
if (in_array($value, $this->enumClass::values())) {
return $value;
}
throw new InvalidArgumentException("Invalid value for enum {$this->enumClass}");
}
}
查询构建器中使用枚举
<?php
use App\Enums\UserRole;
use App\Models\User;
// 查询所有管理员
$admins = User::where('role', UserRole::Admin)->get();
// 使用作用域
$admins = User::admins()->get();
// 批量更新
User::where('role', UserRole::Guest)
->update(['role' => UserRole::User]);
// 比较枚举
$user = User::find(1);
if ($user->role === UserRole::Admin) {
// 执行管理员逻辑
}
表单验证中的枚举支持
<?php
// app/Http/Requests/UserRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Enums\UserRole;
use Illuminate\Validation\Rules\Enum;
class UserRequest extends FormRequest
{
public function rules(): array
{
return [
'role' => ['required', new Enum(UserRole::class)],
];
}
}
Blade 模板中的渲染
{{-- resources/views/users/show.blade.php --}}
@php
$user = \App\Models\User::find(1);
@endphp
用户角色:{{ $user->role->label() }}
{{-- 下拉选择框 --}}
<select name="role">
@foreach(\App\Enums\UserRole::cases() as $role)
<option value="{{ $role->value }}"
@selected($user->role === $role)>
{{ $role->label() }}
</option>
@endforeach
</select>
API 资源中的格式化
<?php
// app/Http/Resources/UserResource.php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'role' => [
'value' => $this->role->value,
'label' => $this->role->label(),
],
];
}
}
最佳实践建议
- 使用 PHP 8.1+ 原生枚举,避免额外依赖
- 数据库层面使用 VARCHAR 而非原生 ENUM,便于迁移
- 总是使用枚举的 values() 方法 生成数据库约束
- 在 Model 中启用 casting,自动转换类型
- 为枚举添加标签方法,便于 UI 展示
- 使用 Laravel 9+ 的枚举验证规则
这种方法既保持了代码的可读性,又确保了数据库层面的数据完整性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播