- What is symfony/deprecation-contracts and do I need it in a Laravel app?
- It is a zero-dependency contract package that provides one global function, trigger_deprecation(), used to emit silenced E_USER_DEPRECATED notices. You only need to require it explicitly if you are building or maintaining a package that emits deprecations. Laravel already pulls it in transitively through Symfony components such as symfony/error-handler, so it is usually present without any action on your part. It registers no service provider, publishes no config, and has no container bindings.
- How do I install symfony/deprecation-contracts with Composer?
- Run composer require symfony/deprecation-contracts and you are done; there is nothing to register in config/app.php or bootstrap/providers.php. Using --dev is reasonable for internal packages whose deprecations only matter while developing or in CI. In most Laravel applications Composer will have installed it already as a transitive dependency, so check composer show before adding it to your own require block.
- Why are my trigger_deprecation() notices not showing up anywhere?
- The function only raises a silenced E_USER_DEPRECATED notice, so nothing becomes visible unless an error handler is wired to capture and route it. Confirm that your error handler and error_reporting settings include E_USER_DEPRECATED for the code path in question, and that the captured notices actually reach a log channel or telemetry sink. Also search your codebase and test bootstrap for an empty function trigger_deprecation() {} declaration, which silently no-ops every call project-wide.
- Does symfony/deprecation-contracts work with Laravel 10, 11 and 12?
- Yes. It is a single-function contract with a stable, effectively frozen API, and it is installed transitively by Symfony components that all current Laravel versions rely on. Composer resolves a compatible release automatically, so Laravel 10, 11 and 12 projects all get a working trigger_deprecation(). The package only requires PHP 7.1 or newer, which every supported Laravel release far exceeds.
- How do I log deprecations to a dedicated channel in Laravel?
- Add a channel such as deprecations to config/logging.php pointing at a dedicated file or your telemetry stack. Then make sure E_USER_DEPRECATED notices are actually captured by the active error handler before they can reach the logger, since the helper itself only emits a silenced notice. A small custom error handler, or a Monolog handler mapped to the deprecation level, is the usual glue between the two.
- Is trigger_deprecation() safe to call in production code paths?
- Yes. It raises a silenced deprecation notice and returns immediately, so it cannot throw, abort a request, or change control flow. The only production concern is noise: if a handler does capture notices, deprecations fired on hot code paths can flood your logs and inflate storage costs. Consider sampling or gating verbose deprecation logging to non-production environments.
- What arguments does trigger_deprecation() require?
- At minimum three: the Composer package name that is triggering the deprecation, the package version that introduced it, and the deprecation message. Any additional arguments are substituted into the message using printf-style formatting, for example trigger_deprecation('acme/pkg', '2.3.0', 'Use "%s" instead of "%s".', 'newFn', 'oldFn'). The emitted output is prefixed with 'Since acme/pkg 2.3.0:', so always pass an exact release version rather than vague placeholders like 'next' or 'upcoming'.
- How do I test that my package triggers the expected deprecations?
- Use PHPUnit's deprecation expectations, such as expectDeprecation() or expectUserDeprecationMessage() on newer versions, or install a custom error handler in the test that collects E_USER_DEPRECATED notices for assertions. PHPUnit can also be configured to fail on unexpected deprecations, which turns your deprecation budget into a CI gate. For internal libraries, assert on the exact 'Since package version:' prefix so version-string discipline does not drift over time.
- What are the alternatives to symfony/deprecation-contracts?
- You can call trigger_error() with E_USER_DEPRECATED directly, which is essentially what the helper wraps, but you lose the standard 'Since package version:' message format that tooling and humans recognize. Other options include PHPUnit's built-in deprecation assertions for tests and bespoke logging helpers inside your own application. The value of this package is convention rather than capability, so alternatives mostly trade standard formatting for extra control.
- Can I disable or ignore deprecation notices entirely?
- Yes, though it is explicitly not recommended: declaring an empty function trigger_deprecation() {} anywhere in your application or test bootstrap suppresses every notice project-wide. Because it is a plain global function, PHP offers no protection against an accidental or vendor-provided override silently muting your signal. If you only want to reduce output in one context, filter at the error handler or log channel instead of shadowing the function.