So I was working on a Symfony 6.0 project where I wanted to try out PHP 8.1 Enums as requirements for routing. But it wasn’t possible yet.
Today I saw the Symfony 6.1.0-BETA1 released blog post and quickly scanned for updates regarding Enum support. And yes, a new feature was listed: [HttpKernel] Add a controller argument resolver for backed enums.
I quickly setup a testing project to play around with this. As the feature is still in beta, I used the command down below to create the project:
composer create-project symfony/skeleton symfony-enum-route -s dev
First thing I did was to create a Backed Enum. All examples seem to create a Card, so I’ll do the same.
<?php
namespace App\Enums;
Enum Card: string
{
case HEARTS = 'hearts';
case DIAMONDS = 'diamonds';
case CLUBS = 'clubs';
case SPADES = 'spades';
}
After that, I added a Controller and a Route.
<?php
namespace App\Controller;
use App\Enums\Card;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class DefaultController extends AbstractController
{
#[Route('/{card}')]
public function __invoke(Card $card): Response
{
return $this->json([
'card' => $card,
]);
}
}
The Card
enum is typed hinted in the controller action (in the __invoke()
method in this case).
Now let’s test this!
First by requesting an existing Card, so that means an existing route /hearts
http https://127.0.0.1:8000/hearts
HTTP/1.1 200 OK
Cache-Control: no-cache, private
Content-Length: 17
Content-Type: application/json
Date: Fri, 15 Apr 2022 20:05:10 GMT
X-Powered-By: PHP/8.1.4
X-Robots-Tag: noindex{
"card": "hearts"
}
That works just fine, we get the 200 OK
response as expected.
And the by requesting a non-existing Card, with the route /foobar
http https://127.0.0.1:8000/foobar
HTTP/1.1 404 Not Found
Cache-Control: no-cache, private
Content-Length: 151964
Content-Type: text/html; charset=UTF-8
Date: Fri, 15 Apr 2022 20:05:47 GMT
X-Powered-By: PHP/8.1.4
X-Robots-Tag: noindex<!-- Could not resolve the "App\Enums\Card $card" controller argument: "foobar" is not a valid backing value for enum "App\Enums\Card" (404 Not Found) -->
We get a 404 Not Found
error page, as expected.
I’ve only been playing around with this for a few moments, but I think this is a very nice feature which I definitely am going to be using in the near future.