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.