keiwen/cacofony
Cacofony is a Laravel/PHP package by keiwen that offers a small, focused set of utilities for common development tasks. It is easy to install and configure, making it suitable for lightweight integrations. Visit the repository for full documentation and usage examples.
What this release is. sensio/framework-extra-bundle 6.0.0 is the Symfony 6 line. It is not a Laravel package — a Laravel developer only meets it when working inside a Symfony codebase, maintaining a shared library, or reviewing a vendor tree. Treat the assessment below as "how the conventions map to what you already know from Laravel" plus the concrete upgrade work.
Minimum steps
# PHP 8.1+ and Symfony 6.x are required by 6.0
composer require sensio/framework-extra-bundle:^6.0
config/bundles.php (Flex does this for you):
Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true]config/packages/sensio_framework_extra.yaml forward. Several keys tied to removed features will now fail with Unrecognized option. Start from an empty/absent file and add back only what you still use.vendor/sensio/framework-extra-bundle/UPGRADE-6.0.md and CHANGELOG.md — the authoritative list of removals.vendor/sensio/framework-extra-bundle/src/Configuration/ — every surviving #[Attribute] class is visible in one directory (Template, Cache, Security, IsGranted, Entity, RestrictToRole, TemplateParameter, …).@Template → #[Template], @Cache → #[Cache], @Security/@IsGranted → #[IsGranted].The 6.0 delta you must plan for
| Change | Impact |
|---|---|
RestrictToRole, TemplateParameter are now attributes, not annotations |
Any docblock usage silently stops being read (or hard-fails if the annotation reader is gone) |
Param fetcher removed (@QueryParam, @RequestParam, @RouteParam) |
Controller arguments validated/injected from the request break at runtime |
Single-method routes removed (@Method) |
HTTP verb restriction moves onto #[Route(methods: [...])] |
ConflictHttpException / LockedHttpException removed |
Now shipped by Symfony itself — change the use statement |
Direction of travel matters: Symfony has been absorbing this bundle's features into core (#[Cache], #[IsGranted], Twig's #[Template], DoctrineBridge's #[MapEntity]). 6.0 is a migration release, not a destination — budget for removing the dependency entirely rather than deepening it.
1. Attribute-first controllers. Everything the bundle still does is now declared with PHP 8 attributes above the method or class:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
#[Route('/orders/{id}', methods: ['GET'])]
#[Cache(smaxage: 3600, public: true)]
#[IsGranted('ROLE_SUPPORT')]
#[Template('order/show.html.twig')]
public function show(Order $order): array
{
return ['order' => $order];
}
2. Replace the removed param fetcher. This is the highest-effort change. Old code:
/**
* @QueryParam(name="page", requirements="\d+", default="1")
* @QueryParam(name="q", requirements="[\w\s]+", default="")
*/
public function index(int $page, string $q) { /* ... */ }
New options, in order of preference:
#[MapQueryParameter] on the argument — closest 1:1 replacement, including regex validation.Request and validate with the Validator component, or bind into a small DTO with #[MapQueryString] (6.3+) / a form.FormRequest: the param fetcher was Symfony's half-hearted version of request validation, and losing it is mostly a win — move the rules into a dedicated input class.3. Replace single-method routes. Move the verb list to the route itself; do not invent a substitute attribute:
#[Route('/webhook', methods: ['POST'])]
If the old @Method was being used as a guard against GET side effects, this is also the moment to confirm CSRF/token handling, exactly as you would check a Laravel route that lost a ->methods() constraint.
4. Swap the HTTP exception imports. The namespaces move to Symfony:
// before
use Sensio\Bundle\FrameworkExtraBundle\...\ConflictHttpException;
// after
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
use Symfony\Component\HttpKernel\Exception\LockedHttpException;
Grep for both class names including in tests and custom exception listeners/maps.
5. RestrictToRole on Doctrine entities. Declare as an attribute on the entity class:
#[RestrictToRole('ROLE_ADMIN')]
class Invoice { /* ... */ }
Because enforcement historically travelled through the request/param resolution pipeline (the same pipeline the param fetcher lived in), verify with a functional test that unauthorized access still 403s. Do not assume the annotation→attribute swap is behaviour-preserving in your setup.
6. Laravel-to-Symfony translation table for shared-library work:
| Laravel | This bundle |
|---|---|
| Route model binding | #[Entity] / ParamConverter |
FormRequest validation |
removed param fetcher → #[MapQueryParameter] or a DTO + Validator |
Gate/can: middleware |
#[IsGranted] |
Cache-Control middleware |
#[Cache] |
abort(409) |
ConflictHttpException |
RestrictToRole and TemplateParameter, and PHP will not warn you. Grep the codebase for @RestrictToRole and @TemplateParameter, then add a functional test asserting the access-control behaviour — a security annotation that stops applying fails open, not closed.Controller "..." requires that you provide a value for the "$page" argument. Search for controllers whose action signatures take scalars not present in the route path — those are the ones that depended on it.sensio_framework_extra keys that referenced removals (request.converters, request.auto_convert, router/view annotation toggles) produce container compile errors. Delete the file first, then re-add incrementally; bin/console cache:clear before and after.doctrine/annotations and the annotations reader config — it is dead weight and an easy win from this upgrade.@Method removal can widen an endpoint. If an action was previously pinned to POST only via @Method and the route itself declared no methods, removing the attribute leaves it accepting all verbs. Audit diffs rather than trusting a green test suite.kernel.exception listener still type-hints the old bundle classes — otherwise your 409/423 handling quietly stops firing.#[Cache], #[IsGranted], Twig #[Template], Doctrine #[MapEntity]). Extend nothing into this bundle; if you are writing new attributes or a custom ParamConverter, write it against the core/DoctrineBridge equivalents instead so the next upgrade is a delete rather than a rewrite.ValueResolver (tag controller.argument_value_resolver), not on anything this bundle exposes — that is where Symfony has consolidated the surviving functionality.How can I help you explore Laravel packages today?