# How about using PHP Enums for Results?

Hey guys,

Weekend post again hehe 😎. I'd like to share my latest approach and I actually find it really cool 🥹.

I've been using PHP Enums not only for options, types, etc but also for Result responses now ⭐️

Lemme show you how it works and how awesome is that 🚀.

## Results over Exceptions

This is one of the practices I've been using and I love it, I also have a post for that: [**No throws and happier life**](https://sethphat.dev/no-throw-and-happier-life)

*TL;DR*:

* Throw is slow
    
* Untyped
    
    * E.g. if your function throws 4 exceptions =&gt; 4 untyped paths.
        
* Increase production errors
    
    * Callers won't usually wrap the `try/catch`
        
* It reduces the reusable purpose of your function
    

I really like how this package [`neverthrow`](https://github.com/supermacro/neverthrow?tab=readme-ov-file#a-note-on-the-package-name) add their reasons as well:

> `Throw`ing and `catching` is very similar to using `goto` statements - in other words; it makes reasoning about your programs harder. Secondly, by using `throw` you make the assumption that the caller of your function is implementing `catch`. This is a known source of errors. Example: One dev `throw`s and another dev uses the function without prior knowledge that the function will throw. Thus, and edge case has been left unhandled and now you have unhappy users, bosses, cats, etc.
> 
> With all that said, there are definitely good use cases for throwing in your program. But much less than you might think.

## Use PHP Enum as the Result

Yeah, here come the main dishes 😎

Everything looks easier with a real-life example, so let's create a `Result` class for creating a Vacation Leave Request.

### The Result class

I will create a `CreateLeaveRequestResult`

```php
enum CreateLeaveRequestResult
{
    /**
     * When the creating leave request is overlap with 
     * another leave requests
     */
    case HAS_CONFLICTED_DATES;

    /**
     * When the user doesn't have enough leave balance
     */
    case INSUFFICIENT_BALANCE;

    /**
     * All good and can create a new leave request
     */
    case SUCCESS;
}
```

As we can see, with some simple notes & cases, we all know the outcome of the function that we are going to trigger. It makes our life easier ✅.

### Handle logic and return the Result

I have a `LeaveRequestService@create` method like this:

```php
class LeaveRequestService
{
    public function create(LeaveRequestData $leave): CreateLeaveRequestResult
    {
        if ($this->hasConflictedDates($leave)) {
            return CreateLeaveRequestResult::HAS_CONFLICTED_DATES;
        }

        if (!$this->hasEnoughBalance($leave)) {
            return CreateLeaveRequestResult::INSUFFICIENT_BALANCE;
        }

        // all good
        $leaveRequest = $this->createNewLeaveRequest($leave);

        // send notifcations or do anything
        // ...

        return CreateLeaveRequestResult::SUCCESS;
    }
}
```

### Response in Controller

```php
public function create(
    LeaveRequestService $service
    SubmitLeaveRequestRequest $request
): JsonResponse {
    $leave = $request->getLeaveRequestData();

    $result = $service->create($leave);
    if ($result !== CreateLeaveRequestResult::SUCCESS) {
        return new JsonResponse([
            'outcome' => $result->name,
        ], 400);
    }

    return new JsonResponse([
        'outcome' => 'SUCCESS',
    ]);
}
```

Awesome right? 😎

## PROs

* Fully typed in your functions.
    
* Better than string/boolean response, especially for complex business logic/flows.
    
* Happier callers, we always know what we'll receive after triggering the functions.
    

## Considerations

### Include additional data when returning the result

Yes, we can, can do either:

* Create a new class which have the Enum result & your additional data
    
* Use my [`never-throw`](https://github.com/shipsaas/never-throw) package (written in PHP)
    
    * Really want to make it as much as same as the TS's neverthrow but still haven't gotten there 🥹.
        

### A bit of marketing

As you see in the above example. It relates to the PTO (personal time off) & Vacation tracker.

If your teams want a simple & awesome solution for that, try out [Flamingo App](https://flamingoapp.com/) 🦩.

It's lovely, gorgeous, super easy to use, and has an awesome notification system that ensures everybody is in the loop 📣.

## Conclusions

Well, that's it guys. I really like this way - making my functions/methods become fully typed.

Happy weekend!
