greg0ire/enum 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

greg0ire/enum

Composer 安装命令:

composer require greg0ire/enum

包简介

work around the missing enum type in php

README 文档

README

This package holds a simple class that may be used as an ancestor for your enum classes.

Build Status

Installation

composer require greg0ire/enum

Usage

Basic usage

Extend the Greg0ire\Enum\AbstractEnum, define your enum key values as constants, and Bob's your uncle. You can make the class abstract or final, as you see fit.

use Greg0ire\Enum\AbstractEnum;

final class DaysOfWeek extends AbstractEnum {
    const Sunday = 0;
    const Monday = 1;
    const Tuesday = 2;
    const Wednesday = 3;
    const Thursday = 4;
    const Friday = 5;
    const Saturday = 6;
}

Then, you may use the DaysOfWeek class for input validation:

DaysOfWeek::isValidName('Humpday');                  // false
DaysOfWeek::isValidName('Monday');                   // true
DaysOfWeek::isValidName('monday');                   // false
DaysOfWeek::isValidName(0);                          // false

DaysOfWeek::isValidValue(0);                         // true
DaysOfWeek::isValidValue(5);                         // true
DaysOfWeek::isValidValue(7);                         // false
DaysOfWeek::isValidValue('Friday');                  // false

Both methods have an assert* counterpart that will throw a Greg0ire\Enum\Exception\InvalidEnumValue exception:

DaysOfWeek::assertValidName(0);                      // InvalidEnumName
DaysOfWeek::assertValidValue('Friday');              // InvalidEnumValue

Additionally, you may get all the constants in your class as a hash:

DaysOfWeek::getConstants();
DaysOfWeek::getConstants('strtolower'); // Will combine your values with `DaysOfWeek::getKeys($callback)`.
DaysOfWeek::getConstants('strtolower', true); // Values combine with `DaysOfWeek::getClassPrefixedKeys($callback)`.
DaysOfWeek::getConstants('strtolower', true, '.'); // Same with `DaysOfWeek::getClassPrefixedKeys($callback, $separator)`.

You may also get all the keys in your class as an array:

DaysOfWeek::getKeys();
DaysOfWeek::getKeys('strtolower'); // Will call `array_map` with the given callback.

Or the key with the enum class prefix:

DaysOfWeek::getClassPrefixedKeys();
DaysOfWeek::getClassPrefixedKeys('strtolower'); // Will call `array_map` with the given callback.
DaysOfWeek::getClassPrefixedKeys('strtolower', '.'); // Replace the namespace separator ('_' by default).

If you would like to get the keys from a value:

$key = DaysOfWeek::getKeysFromValue(1); // Monday will be assigned to $key

If you have many keys with the same value you will get an array, and a value otherwise.

Advanced usage

If you need to get the constants from a class you cannot modify, or from an interface, or even from several classes / interfaces, you may override AbstractEnum::getEnumTypes().

For example, if you have the following class and interface :

namespace Vendor\Namespace;

class ClassFromAVendor
{
   const SOMETHING      = 'something';
   const SOMETHING_ELSE = 'something_else';
}
namespace My\Namespace;

interface SomeInterface
{
   const ANOTHER_CONST = 'another_const';
}

You can get all three constants by creating this Enum :

use Greg0ire\Enum\AbstractEnum;
use My\Namespace\SomeInterface;
use Vendor\Namespace\ClassFromAVendor;

final class MyEnum extends AbstractEnum
{
    protected static function getEnumTypes()
    {
        return [ClassFromAVendor::class, SomeInterface::class];
    }
}

Alternatively, you can specify a prefix for each type to avoid getting FQCNs in the hash keys.

use Greg0ire\Enum\AbstractEnum;
use My\Namespace\SomeInterface;
use Vendor\Namespace\ClassFromAVendor;

final class MyEnum extends AbstractEnum
{
    protected static function getEnumTypes()
    {
        return [
            'prefix1' => ClassFromAVendor::class,
            'prefix2' => SomeInterface::class,
        ];
    }
}

Get label from a service

If you want to get the constant label behind an enum value, you can instantiate the GetLabel class and invoke it.

use Greg0ire\Enum\Bridge\Symfony\Translator\GetLabel;

$label = new GetLabel();
$label(Your\Enum\Class::VALUE, Your\Enum\Class::class);

To enable translation, require the symfony/translation component and pass a Symfony\Contracts\Translation\TranslationInterface instance on the GetLabel constructor

use Greg0ire\Enum\Bridge\Symfony\Translator\GetLabel;
use Symfony\Contracts\Translation\TranslationInterface;

$label = new GetLabel($translator);
$label(Your\Enum\Class::VALUE, Your\Enum\Class::class);

If you're using Symfony, alias the service and simply inject it. If translations are enabled, the TranslatorInterface will be automatically injected.

services:
    # ...
    Greg0ire\Enum\Bridge\Symfony\Translator\GetLabel: "@greg0ire_enum.symfony.translator.get_label"
public function index(GetLabel $label)
{
    $label(Your\Enum\Class::VALUE, Your\Enum\Class::class);
    $label(Your\Enum\Class::VALUE, Your\Enum\Class::class, 'another_domain'); // Change the translation domain
    $label(Your\Enum\Class::VALUE, Your\Enum\Class::class, false); // Disable translation. In this case the class prefix wont be added
    $label(Your\Enum\Class::VALUE, Your\Enum\Class::class, false, true); // Disable translation but keep class prefix
    $label(Your\Enum\Class::VALUE, Your\Enum\Class::class, false, true, '.'); // Disable translation but keep class prefix with a custom separator
}

Integration with other libraries

greg0ire/enum integrates with other libraries. The list is available in the suggest section of the Composer dependency manifest.

Symfony validator

This package provides a "ready to use" symfony validator. You have to require the symfony/validator package to get it working.

use Greg0ire\Enum\Bridge\Symfony\Validator\Constraint\Enum;
use Symfony\Component\Validator\Validation;
use Your\Namespace\EnumClass;

$validator = Validation::createValidator();

$violations = $validator->validateValue(42, new Enum(EnumClass::class));
// You can also show the constants keys on the error message:
$violations = $validator->validateValue(42, new Enum(['class' => EnumClass::class, 'showKeys' => true]));
// Enum constraint inherits from Choice constraint. You can use inherited options too:
$violations = $validator->validateValue(42, new Enum(['class' => EnumClass::class, 'strict' => true]));

Another example with annotations:

use Doctrine\Common\Annotations\AnnotationRegistry;
use Greg0ire\Enum\Bridge\Symfony\Validator\Constraint\Enum as EnumAssert;
use Symfony\Component\Validator\Validation;

class MyClass
{
    /**
     * @EnumAssert("Your\Namespace\EnumClass")
     */
    private $dummy;

    public function __construct($dummy)
    {
        $this->dummy = $dummy
    }
}

AnnotationRegistry::registerLoader('class_exists');
$validator = Validation::createValidatorBuilder()
    ->enableAnnotationMapping()
    ->getValidator();

$object = new MyClass(42);

$violations = $validator->validate($object);

Note: You will have to get doctrine/annotations and doctrine/cache packages to get it working.

Symfony form

This package provides a "ready to use" symfony form type. You have to require the symfony/form package to get it working.

use Greg0ire\Enum\Bridge\Symfony\Form\Type\EnumType;
use Symfony\Component\Form\Forms;
use Your\Namespace\EnumClass;

$formFactory = Forms::createFormFactory();

$view = $this->factory->create(EnumType::class, null, array(
    'class' => EnumClass::class,
))->createView();

Twig extension

This package comes with an EnumExtension Twig class. It contains a filter and some functions. You have to require the twig/twig package to get it working.

Filter

The enum_label filter will try to return the constant label corresponding to the given value.

This filter relies on the Greg0ire\Enum\Bridge\Symfony\Translator\GetLabel service.

It will try to translate it if possible. To enable translation, require the symfony/translation component and pass a Symfony\Contracts\Translation\TranslationInterface instance on the GetLabel constructor. GetLabel instance will be injected on the EnumExtension constructor.

If translation is not available, you will have the default label with class prefixing.

Usage:

{{ value|enum_label('Your\\Enum\\Class') }}
{{ value|enum_label('Your\\Enum\\Class', 'another_domain') }} {# Change the translation domain #}
{{ value|enum_label('Your\\Enum\\Class', false) }} {# Disable translation. In this case the class prefix wont be added #}
{{ value|enum_label('Your\\Enum\\Class', false, true) }} {# Disable translation but keep class prefix #}
{{ value|enum_label('Your\\Enum\\Class', false, true, '.') }} {# Disable translation but keep class prefix with a custom separator #}
Functions

The 3 available twig functions are ports of some AbstractEnum methods that can be useful in a twig template:

  • enum_get_constants => AbstractEnum::getConstants
  • enum_get_keys => AbstractEnum::getKeys
  • enum_get_class_prefixed_keys => AbstractEnum::getClassPrefixedKeys

The arguments are exactly the same except you have to specify the targeted class first (as enum_label filter).

Here is a concrete example with enum_get_constants function:

{% for enum_key, enum_value in enum_get_constants('Your\\Enum\\Class') %}
    {{ enum_key }} -> {{ enum_value }}
{% endfor %}
Twig extension as a service

On Symfony projects, the extension can be autoloaded. First, you have to require the symfony/framework-bundle and symfony/twig-bundle packages, or use Symfony fullstack.

Then, register the bundle in the kernel of your application:

// app/AppKernel.php

public function registerBundles()
{
    $bundles = [
        // ...
        new Greg0ire\Enum\Bridge\Symfony\Bundle\Greg0ireEnumBundle(),
    ];

    // ...

    return $bundles
}

That's all. You can now directly use the filter.

Contributing

see CONTRIBUTING.md

Credits

This is a shameless rip-off of this Stack Overflow answer, with one modification: the getConstants method has been made public so that it is available for building choice widgets, for instance. If you want to give credit to someone for this, give it to Brian Cline

greg0ire/enum 适用场景与选型建议

greg0ire/enum 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 396.98k 次下载、GitHub Stars 达 45, 最近一次更新时间为 2014 年 06 月 17 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「symfony」 「form」 「validator」 「enum」 「enumeration」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 greg0ire/enum 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 greg0ire/enum 我们能提供哪些服务?
定制开发 / 二次开发

基于 greg0ire/enum 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 396.98k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 47
  • 点击次数: 23
  • 依赖项目数: 11
  • 推荐数: 0

GitHub 信息

  • Stars: 45
  • Watchers: 2
  • Forks: 4
  • 开发语言: PHP

其他信息

  • 授权协议: CC-BY-SA-3.0
  • 更新时间: 2014-06-17