somnambulist/doctrine-enum-bridge

此软件包已被废弃,不再维护。作者建议使用somnambulist/domain软件包。

允许使用Doctrine类型系统与任何枚举库一起使用。

1.2.0 2017-10-24 00:09 UTC

This package is auto-updated.

Last update: 2020-02-03 17:24:20 UTC


README

此仓库已被存档。请更新到组合包。

Doctrine 枚举桥接器

提供不同枚举实现与 Doctrine 之间的桥接。任何类型的 PHP 可枚举(例如 Eloquent\Enumeration 或 myclabs/php-enum)都可以使用此适配器。

如果没有提供序列化器,将使用默认的字符串转换序列化器。

所有枚举都使用数据库的本地 varchar 格式存储。如果您想使用自定义的数据库类型,请扩展并重新实现 getSQLDeclaration() 方法。

要求

  • PHP 7+
  • Doctrine 2.5+

安装

使用 composer 安装,或从 github.com 检出/提取文件。

  • composer require somnambulist/doctrine-enum-bridge

使用方法

在框架的应用程序服务提供程序/包的启动方法中,注册您的枚举和适当的可调用来创建/序列化。如果没有提供,将使用将可枚举转换为字符串的默认序列化器。

回调将接收

  • value - 当前值,可以是 PHP 类型或数据库类型(用于构造函数)
  • name - 绑定给枚举的名称,可能是完全限定名
  • platform - Doctrine AbstractPlatform 实例

例如,在 Symfony 项目中,在您的 AppBundle 类中

class AppBundle extends Bundle
{
    public function boot()
    {
        EnumerationBridge::registerEnumType(Action::class, function ($value) {
            if (Action::isValid($value)) {
                return new Action($value);
            }

            throw new InvalidArgumentException(sprintf(
                'The value "%s" is not valid for the enum "%s". Expected one of ["%s"]',
                $value,
                Action::class,
                implode('", "', Action::toArray())
            ));
        });
    }
}

在 Laravel 中,添加到您的 AppServiceProvider (registerboot 都应该有效)

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        EnumerationBridge::registerEnumType(Action::class, function ($value) {
            if (Action::isValid($value)) {
                return new Action($value);
            }

            throw new InvalidArgumentException(sprintf(
                'The value "%s" is not valid for the enum "%s". Expected one of ["%s"]',
                $value,
                Action::class,
                implode('", "', Action::toArray())
            ));
        });
    }
}

注意:桥接器将检查类型是否已注册,如果是,则跳过它。如果您想替换现有的类型,则应使用 Type::overrideType(),但这只适用于已注册的类型。

注册多个类型

可以通过调用 registerEnumTypes() 并传递一个枚举名称和数组的可调用来一次性注册多个枚举,其中包含构造函数和序列化器或只是构造函数。

class AppBundle extends Bundle
{
    public function boot()
    {
        EnumerationBridge::registerEnumTypes(
            [
                'gender' => [
                    function ($value) {
                        if (Gender::isValidValue($value)) {
                            return Gender::memberByValue($value);
                        }
            
                        throw new InvalidArgumentException(sprintf(
                            'The value "%s" is not valid for the enum "%s"', $value, Gender::class
                        ));
                    },
                    function ($value, $platform) {
                        return is_null($value) ? 'default' : $value->value();
                    }
                ]
            ]
        );
    }
}

在 Doctrine 映射文件中的使用

在您的 Doctrine 映射文件中,只需设置字段的类型。

fields:
    name:
        type: string
        length: 255
    
    gender:
        type: gender
    
    action:
        type: AppBundle\Enumerable\Action

共享构造函数

对于具有相同签名/方法名的可枚举,可以共享构造函数可调用。

要共享构造函数可调用,使用可枚举的完全限定名作为名称,或者您可以使用别名到可枚举的哈希映射

class AppBundle extends Bundle
{
    public function boot()
    {
        $constructor = function ($value, $class) {
            // constructor method should handle nulls
            if (is_null($value)) {
                return null;
            }
        
            if ($class::isValid($value)) {
                return new $class($value);
            }
        
            throw new InvalidArgumentException(sprintf(
                'The value "%s" is not valid for the enum "%s". Expected one of ["%s"]',
                $value,
                $class,
                implode('", "', $class::toArray())
           ));
        }
    
        EnumerationBridge::registerEnumType(Action::class, $constructor);
        EnumerationBridge::registerEnumType(Country::class, $constructor);
        EnumerationBridge::registerEnumType(Currency::class, $constructor);
    }
}

由于每个可枚举都可以映射到其自己的构造/序列化处理程序,因此可以使用此桥接器处理来自 Eloquent\Enumerable 库的复杂多分。

链接