Where to put/how to handle enums in Laravel?
Laravel有一个
1 2 3 4 5 | $phoneTypes = [ 'CELL' =>"Cellular", 'HOME' =>"Home", 'WORK' =>"Work", ]; |
我想在视图/模板和数据库中使用:
1 2 3 4 5 | Schema::create('customers', function (Blueprint $table) { $table->increments('id'); $table->enum('pri_phone_type',array_keys($phoneTypes)); ... }); |
我不同意这里接受的回答。我觉得Enums对这类事情非常有用。我更喜欢将枚举视为类型,并在枚举基类上实现所需的方法,以提供所需的功能,如获取字典。
我的简单示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 | abstract class PhoneType extends Enum { const Cell ="Cellular"; const Home ="Home"; const Work ="Work"; } abstract class Enum { static function getKeys(){ $class = new ReflectionClass(get_called_class()); return array_keys($class->getConstants()); } } |
示例用法:
1 | PhoneType::getKeys(); |
有关详细信息和更深入的示例,请参阅PHP和枚举。
您有几个处理枚举的选项。不过,在我们看一些之前,我首先强烈建议您不要使用db
数据库枚举有很多问题。我建议阅读本文,例如:
http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/
因此,我们来看看其他一些选择。
使用Laravel配置由于您使用的是laravel,一个非常简单的选项是在配置文件中插入一个选项数组。
假设您创建了一个新文件
1 2 3 4 5 6 7 | return [ 'phone_types' => [ 'CELL' =>"Cellular", 'HOME' =>"Home", 'WORK' =>"Work", ] ]; |
现在,您可以在代码中的任何地方访问
@Banford的答案显示了如何使用类常量执行基本的枚举类型行为。如果您喜欢这种方法,我建议您查看本文和基于此概念的包,以提供强类型枚举:
https://sticker.io/blog/php-enums
https://github.com/spatie/enum
您将创建这样的类:
1 2 3 4 5 6 7 8 | /** * @method static self cell() * @method static self home() * @method static self work() */ class PhoneTypes extends Enum { } |
现在您可以在应用程序中调用
如果您真的想在数据库中管理您的选项,我将创建一个单独的
基于@banfords answer,php7常量现在可以是数组:
1 2 3 4 5 6 7 8 9 10 11 12 | class User extends Authenticatable { /** * The possible genders a user can be. */ const GENDER = [ 'Male', 'Female', 'Unspecified' ]; ... |
除了@banford的回答:
我最近把一个包放在一起,使在拉拉维尔使用Enums更好。这是我在研究如何做相同的事情时发现的各种实现的组合(因此我来这里的原因)。
https://github.com/bensampo/laravel-enum
在这种情况下,您可以执行如下操作:
1 2 3 4 5 6 | final class PhoneTypes extends Enum { const Cellular = 0; const Work = 1; const Home = 2; } |
然后可以使用以下方法访问这些值:
1 | PhoneTypes::Work // 1 |
我建议总是将这些值设置为整数,然后将它们作为整数存储在数据库中。
基枚举类具有将所有键和值作为数组获取的方法。该包还提供了一些其他的好处,在这种情况下可能很有用,比如验证,这样用户就不能向数据库添加不存在的值。
还有一个非常方便的发电机。
我希望这对某人有用。
只是有类似的问题,对我来说,雄辩的存取器和变异器工作得最好。对于这个问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | namespace App; use Illuminate\Database\Eloquent\Model; class Customer extends Model { /** * @var array */ protected $phoneTypes = [ 'Cellular', 'Home', 'Work' ]; /** * @param int $value * @return string|null */ public function getPhoneTypeAttribute($value) { return Arr::get($this->phoneTypes, $value); } } |
请注意,在数据库中,您应该保存数值,其中0是单元格,1是主单元格,2是工作单元格。其次,在这里使用翻译代替受保护的财产是明智的。
您根本不应该使用枚举。
官方的Laravel 5.1文件规定:
Note: Renaming columns in a table with a enum column is not currently supported.
当数据库表中有一个
Unknown database type enum requested
即使使用Laravel 5.8,问题也无法解决。
我需要补充的是,在向
我得出的结论是,您应该小心使用枚举。或者甚至不应该使用枚举。
下面是一个例子,说明在
假设你有这个:
1 2 3 4 | Schema::create('blogs', function (Blueprint $table) { $table->enum('type', [BlogType::KEY_PAYMENTS]); $table->index(['type', 'created_at']); ... |
你需要更多的类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public function up(): void { Schema::table('blogs', function (Blueprint $table) { $table->dropIndex(['type', 'created_at']); $table->enum('type_tmp', [ BlogType::KEY_PAYMENTS, BlogType::KEY_CATS, BlogType::KEY_DOGS, ])->after('type'); }); DB::statement('update `blogs` as te set te.`type_tmp` = te.`type` '); Schema::table('blogs', function (Blueprint $table) { $table->dropColumn('type'); }); Schema::table('blogs', function (Blueprint $table) { $table->enum('type', [ BlogType::KEY_PAYMENTS, BlogType::KEY_CATS, BlogType::KEY_DOGS, ])->after('type_tmp'); }); DB::statement('update `blogs` as te set te.`type` = te.`type_tmp` '); Schema::table('blogs', function (Blueprint $table) { $table->dropColumn('type_tmp'); $table->index(['type', 'created_at']); }); } |