PHP Enums tryFrom Method

PHP Enums tryFrom Method

I was recently working on a project where I was receiving data from an API that had a payment_type. I converted the payment_type into the enum below:

enum PaymentType: string 
{
    case CREDIT_CARD = 'credit_card';
    case APPLE_PAY = 'apple_pay';
    case GOOGLE_PAY = 'google_pay';
    case PAYPAL = 'paypal';
    case SHOP_PAY = 'shop_pay';
}

Then, I use this enum in the data transfer object (DTO) to define the structure of the data I receive from the API.

However, the problem I was running into is the payment_type is not always in the response of the API data, so it could be null. In my DTO, I have a from method to build the object from the API response which looks like the following:

class OrderDto
{
    ...
    public static function from(array $data): self {
        return new self(
            ...
            payment_method: isset($data['payment_method']) ? PaymentType::from($data['payment_method']) : null,
        );
    }
}

I had to check if the payment_method is set too, because otherwise, a ValueError exception will be thrown.

This is where the tryFrom method comes in handy. If payment_method is null or is not a valid case for the enum, it will just return null without throwing an exception. So now, the DTO can be updated to the following which is much cleaner:

class OrderDto
{
    ...
    public static function from(array $data): self {
        return new self(
            ...
            payment_method: PaymentType::tryFrom($data['payment_method']),
        );
    }
}

Please note that this only works for backed enums in PHP 8.1+. In case you’re not familiar, a BackedEnum is one where each case has a value specified. So in the example above, the enum is a string-backed enum since it is defined with enum PaymentType: string.

This would not work for a standard PHP enum like the one below:

// Not a backed enum so does not include from and tryFrom methods.
enum PaymentType 
{
    case CREDIT_CARD;
    case APPLE_PAY;
    case GOOGLE_PAY;
    case PAYPAL;
    case SHOP_PAY;
}

If you found this tip helpful, I also have a similar one with the Carbon PHP make method. You can read that here.

Did you find this article valuable?

Support Sean Kegel by becoming a sponsor. Any amount is appreciated!