如何在 PHP 8.1 Enums 中实现 EnumClass::$userInput?

huangapple go评论65阅读模式
英文:

how to implement EnumClass::$userInput on php 8.1 Enums?

问题

我一直在学习 PHP 8.1 中的新枚举特性,结合 Laravel 构建电子商务内容管理系统。我对 SOLID 原则是全新的。

这是我的枚举类:

enum PaymentMethods : string
{
    case PAYPAL  = '使用 PayPal 支付';
    case STRIPE  = '使用 Stripe 支付';
}

在结账页面,用户可以选择其中一种支付方式,如下所示:

<select name="delivery_method">
    @foreach(DeliveryMethods::cases() as $case)
        <option value="{{ $case->name }}">{{ $case->value }}</option>
    @endforeach
</select>

假设我们在视图中有 PAYPAL 的值(这个值来自用户输入),我们希望从 PaymentMethods 枚举类中获取 PAYPAL 的值。

一种方法是使用 foreach 循环,如下所示:

<p>
    @foreach(DeliveryMethods::cases() as $case)
        @if(request()->get('payment_method') == $case->name)
            {{ $case->value }}
        @endif
    @endforeach
</p>

但我想在不同地方和多次使用这个逻辑,除了使用 foreach 循环,基于 SOLID 原则是否有更好的方式?

英文:

I have been learning the new enums introduction on php 8.1 with laravel for an eccomerce cms. i'm brandly new on SOLID principles.

This this my Enum class:

enum PaymentMethods : string
{
    case PAYPAL  = &#39;pay with paypal&#39;;
    case STRIPE  = &#39;pay with stripe&#39;;
}

On checkout page user can select one of Payment Methods like this:

&lt;select name=&quot;delivery_method&quot;&gt;
    @foreach(DeliveryMethods::cases() as $case)
        &lt;option value=&quot;{{ $case-&gt;name }}&quot;&gt;{{ $case-&gt;value }}&lt;/option&gt;
    @endforeach
&lt;/select&gt;

let's assume that we have PAYPAL value (which is taken from user input), in the view and we want to access the value of PAYPAL from PaymentMethods Enum class,

one method is that i use a foreach loop like this:

&lt;p&gt;
    @foreach(DeliveryMethods::cases() as $case)
        @if(request()-&gt;get(&#39;payment_method&#39;) == $case-&gt;name)
            {{ $case-&gt;value }}
        @endif
    @endforeach
&lt;/p&gt;

but i want to use this logic in different places and on many times,
is there any better way instead of doing this, based on solid prinsiples?

答案1

得分: 2

您可以通过使用支持的枚举提供的方法之一以及nullsafenull coalesce运算符来缩短您的代码。

{{ DeliveryMethods::tryFrom(request()->get('payment_method'))?->value ?? 'some default value' }}

如果您希望在传递无效的枚举值时使代码失败而不是处理空值,可以使用from(...)代替tryFrom(...)

这假设您正在使用values来访问案例。如果您使用名称,则会更加复杂。您可以在枚举中实现静态方法:

enum PaymentMethods : string
{
    case PAYPAL  = 'pay with paypal';
    case STRIPE  = 'pay with stripe';
    
    public static function fromName(string $method): ?PaymentMethods
    {
        foreach(PaymentMethods::cases() as $case) {
           if ($case->name === $method) {
              return $case;
            }
        }
        return null;
    }
}

然后您可以这样使用它:

PaymentMethods::fromName(request()->get('payment_method'));

示例

您还可以将该方法移动到其他地方的帮助类中。

英文:

You can shorten your code by using one of the methods provided for backed enums and the nullsafe and null coalesce operators.

{{ DeliveryMethods::tryFrom(request()-&gt;get(&#39;payment_method&#39;))?-&gt;value ?? &#39;some default value&#39; }}

You can use from(...) instead of tryFrom(...) if you want your code to fail if an invalid enum value is passed instead of dealing with nulls.

This is assuming you are using the values to access the cases. If you are using the name then it gets trickyer. You can implement static methods in enums:

enum PaymentMethods : string
{
    case PAYPAL  = &#39;pay with paypal&#39;;
    case STRIPE  = &#39;pay with stripe&#39;;
    
    public static function fromName(string $method): PaymentMethods
    {
        foreach(PaymentMethods::cases() as $case) {
           if ($case-&gt;name === $method) {
              return $case;
            }
        }
        return null;
    }
}

Then you can use it as:

PaymentMethods::fromName(request()-&gt;get(&#39;payment_method&#39;));

Example

You can also move that method to a helper class somewhere else.

答案2

得分: 0

你可以像这样操作

PaymentMethods::{$selected_method}->value

注意:这里的 $selected_method 是您从视图中获取的值。

或者您可以在您的枚举类中定义一个 method。在该方法中,您将传递一个作为字符串的 delivery method 名称,并该方法将评估所选方法的值。例如

在枚举类中定义该方法
public function getVal($method)
{
   $this::{$method}->value;
}
通过这种方式在任何地方调用它
PaymentMethods::getVal("PAYPAL");
英文:

You can do something like that

PaymentMethods::{$selected_method}-&gt;value

> Note: here $selected_method is the value you obtain from view by user.

or you can define a method in your enum class. In that method, you will pass a delivery method name as a string and that method will evaluate the value of a selected method. i.e.

Define that method in the enum class
public function getVal($method)
{
   $this::{$method}-&gt;value;
}

call it anywhere by this way
PaymentMethods::getVal(&quot;PAYPAL&quot;);

huangapple
  • 本文由 发表于 2023年2月24日 17:31:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75554821.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定