如何在 Symfony Doctrine 中使用实际的 ENUM 类型?
ENUM 类型很棒。它们允许严格的值限制并使代码重构变得容易。不幸的是,PHP 不仅在 8.1 版本之前缺乏这些,而且 Doctrine DBAL 也缺乏,并且没有提供开箱即用的易于使用的解决方案。我正在寻找一个解决方案,允许我:
- DB中的本机ENUM类型
- PHP中没有魔术字符串
- 尽可能少的代码重复
- PHP 7.4+(不能使用PHP 8.1)
对于那些寻找此类解决方案的人来说,这个问题是自我回答的,因为经过几个小时的奋斗,我对自己所做的事情感到非常自豪。请看下文,希望对您有所帮助:
ENUM types are awesome. They allow strict value restrictions and make code refactoring easy. Unfortunately, PHP not only lacks these until version 8.1, the Doctrine DBAL also lacks behind and does not offer a easy to use solution out of the box. I was looking for a solution that would allow me:
- native ENUM type in DB
- no magic strings in PHP
- as little code repetition as possible
- PHP 7.4+ (cannot use PHP 8.1)
This question is to be self-answered for those looking for such solution, because after hours of struggle, I am quite proud of what I made. See below, hope it helps:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先创建一个扩展
Doctrine\DBAL\Types\Type
的抽象基类。这允许它用作实体列声明中的类型。其基础归功于 @Brian Cline
重要的是此类通过 Reflection 提供了一些辅助函数,但它还有继承的功能,允许它用作实际的数据库类型。我将通过下面的例子向您展示用法。
这就是定义新 ENUM 类型的方式:
非常简单,对吧?这个开箱即用的功能允许您在 PHP 中实现一些很酷的功能,例如:
但我们仍然没有在数据库表中实现实际的 ENUM 类型。为此,首先将以下内容添加到您的
config/packages/doctrine.yaml
中:这会将 DB
ENUM
类型映射到本地string
类型(抱歉) ,本机 ENUM 不在此解决方案中,但对于 PHP 8.1 可能(?)。)最后一步是您的 Entity 类:
如您所见,如果您尝试执行以下操作,代码将引发异常设置一些不允许的字符串你的枚举。
当您进行迁移时,输出应该如下所示:
就是这样。当您使用 PHP 时,请记住使用
AdminRoleType::
类而不是魔术字符串。如果您需要在枚举中添加/删除项目,只需从枚举类中添加/删除public const
即可。Start by creating an abstract base class which extends
Doctrine\DBAL\Types\Type
. This allows it to be used as a type in Entity column declarations.Credit for the base of this goes to @Brian Cline
Whats important is that this class provides some helper functions with Reflection, but it also has inherited functions that allow it to be used as actual DB type. I will show you the usage with an example below.
This is how you define a new ENUM type:
Pretty simple, right? This out of the box allows you to some cool things in PHP such as:
But still we did not achieve actual ENUM type in our DB table. To do this, first add the following to your
config/packages/doctrine.yaml
:This maps DB
ENUM
type to localstring
type (sorry, native ENUMs are not in this solution, but for PHP 8.1 could(?) be possible.)The last step is your
Entity
class:As you can see the code will throw an exception if you try to set some string that is not allowed value for your ENUM.
And when you do migration, the output should look like:
That's it. When you work in PHP, remember to use
AdminRoleType::
class instead of magic strings. If you need to add/remove item in enum, just add/removepublic const
from the enum class.