How to trigger error when there is deprecation warning in PHP?

234 views Asked by At

I have a library, and I didn't notice that it was giving deprecation warnings until someone created an issue on GitHub. I've enabled:

error_reporting(E_ALL);

And fixed all deprecation warnings. But the question is: can you make the code always fail (I think about unit tests) if there are deprecation warnings? I was thinking maybe about adding ob_ buffering with a regular expression to test if there are no warnings and throw an error. But this would require some code that will not look pretty.

Is there an easy way to just toggle some options to make warnings real errors? So the unit test doesn't pass and the code always fails? I want my code to be future-proof and don't fail when PHP decides to replace deprecation with real error.

2

There are 2 answers

0
Karl Hill On BEST ANSWER

Yes, you can make your own PHP script treat all (handle-able) errors, including E_DEPRECATED/E_USER_DEPRECATED by turning them into exceptions with your own error handler function.

See PHP's set_error_handler() function. It allows you to define a custom error handler that will be called whenever an error occurs (of level E_ALL by default, excluding some core errors that do fatal and ignore such a handler, clearly documented on its manual page).

set_error_handler(
    function($errno, $errstr, $errfile, $errline) {
       throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
    },
    E_DEPRECATED | E_USER_DEPRECATED
);

Register it after the unit testing framework registers it's own handler or communicate with the testing framework accordingly, e.g. per configuration. See their feature list, this above is pure PHP code.

0
CAAHS On

But the question is: can you make the code always fail (I think about unit tests)

Use the <phpunit failOnDeprecation="true"> attribute¹, PHPUnit shows a D in the standard test-runner when a deprecation occured during tests (E_DEPRECATED, E_USER_DEPRECATED, or PHPUnit deprecation).

This will make it always fail then.

Command line options exist, too, taken from phpunit --help invocation:

Switch Description
‑‑display‑deprecations "Display details for deprecations triggered by tests". See what is behind each D.
‑‑fail‑on‑deprecation "Signal failure using shell exit code when a deprecation was triggered". This is the equivalent of the failOnDeprecation XML attribute above.
‑‑stop‑on‑deprecation "Stop after first test that triggered a deprecation". Fail fast. This is the stopOnDeprecation XML attribute.

Not in (your) case of PHP language deprecation, but perhaps noteworthy for a future visitor:

PHPUnit doesn't populate the information about @-suppressed triggered E_USER_DEPRECATED errors. To make it working with PHPUnit nevertheless, use the -d xdebug.scream=1 PHP (not PHPUnit) command line parameter for the ini setting of the Xdebug extension. Setup xdebug.mode appropriately, for xdebug.scream the development helpers² must be enabled (-d xdebug.mode=develop, often default). If other features from Xdebug are also required for PHPUnit, codecoverage for example, append the mode with a comma (","). More information is available in the Xdebug documentation.


  1. The failOnDeprecation Attribute — PHPUnit 5. The XML Configuration File
  2. Development Helpers — Xdebug: Documentation