php 通过字符串从枚举中获取Case

2ul0zpep  于 2023-06-28  发布在  PHP
关注(0)|答案(4)|浏览(160)

我寻找一个简单的解决方案来通过字符串获得枚举的大小写。有BackedEnums。例如:

<?php
enum Status: string
{
    case OK = "OK";
    case FAILED = "FAILED";
    ...
}
$status = Status::tryFrom("OK"); // or from("OK");

但我不想为了得到这个结果而写两遍同一个词。有没有一种原生的方法可以在不使用BackedEnums的情况下获得案例?我想要的是:

<?php
enum Status
{
    case OK;
    case FAILED;
    ...
}
$status = Status::get("OK"); //returns Status::OK;

或者我需要写我自己的功能吗?例如:

enum Status
{
    case OK;
    case FAILED;    
    public static function get(string $name): null|Status
    {
        $name = strtoupper(trim($name));
        if(empty($name))
            return null;

        foreach(Status::cases() as $status)
        {
            if($status->name == $name)
                return $status;
        }
        return null;
    }
}

Status::get("OK"); // -> Status::OK

有没有更好的方法来达到同样的效果?

mgdq6dx1

mgdq6dx11#

这里有一个内部名称获取器,如下所示。
Status::OK->name;
返回Ok
Status::OK->value;
这将返回值
从值中获取事例。用这个
$case = Status::tryFrom('Ok')
https://www.php.net/manual/en/backedenum.tryfrom.php

nnt7mjpx

nnt7mjpx2#

ReflectionEnum是答案。在php8.1中枚举的rfc中有一章是反射
这里有一个方法getCase(string $name),与getValue()结合得到枚举。使用该函数,您可以通过字符串值获得大小写。
您的示例如下所示:

$status = (new ReflectionEnum("Status"))->getCase("OK")->getValue();

最好与ExceptionHandler一起使用,因为如果未找到传输的字符串,则可能会以ReflectionException结束

bweufnob

bweufnob3#

遗憾的是,只有BackedEnumfromtryFrom方法可用,但它们可以很容易地被 polyfilled,下面是如何在trait中编写自己的fromtryFrom以实现可重用性的方法。

<?php

trait LazyEnum
{
    public static function tryFrom($caseName): ?self
    {
        $rc = new ReflectionEnum(self::class);
        return $rc->hasCase($caseName) ? $rc->getConstant($caseName) : null;
    }

    /**
     * @throws Exception
     */
    public static function from($caseName): self
    {
        return self::tryFrom($caseName) ?? throw new Exception('Enum '. $caseName . ' not found in ' . self::class);
    }

}

enum Test
{
    use LazyEnum;
    
    case FOO;
    case BAR;
}
var_dump(Test::tryFrom('FOO')); //enum(Test::FOO)
var_dump(Test::tryFrom('BAZ')); //NULL
wyyhbhjk

wyyhbhjk4#

您可以使用https://packagist.org/packages/henzeb/enumhancer,而不是自己编写
这将为你做你所需要的,以及更多。

相关问题