Deprecation notice vs fatal error: which PHP warnings actually matter
Short answer
Only a fatal error stops the page. Warnings, notices and deprecation notices let it finish; a deprecation notice means the code needs a change before a future PHP version. Visitors should never see any of them: on a live site, keep WP_DEBUG off, or log messages instead of displaying them. Hiding a message doesn’t fix it, so find the plugin behind it and update or report it. If the site is actually broken, look for the fatal error first.
The four kinds of PHP messages
Every PHP message starts with its kind. Only the first one stops the page:
| The message starts with | What PHP does | What it means for your site |
|---|---|---|
| Fatal error | Stops. The rest of the page isn’t built. | Broken: WordPress shows “There has been a critical error on this website.” |
| Warning | Carries on. | Something went wrong just now; part of the page may be missing. |
| Notice | Carries on. | Something that may be a mistake, or may be normal. |
| Deprecated | Carries on, exactly as before. | Works today; needs a change before a future PHP version. |
These are php.net’s own descriptions of the four levels (php.net):
- Fatal errors: “Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is halted.”
- Warnings: “Run-time warnings (non-fatal errors). Execution of the script is not halted.”
- Notices: “Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script.”
- Deprecation notices: “Enable this to receive warnings about code that will not work in future versions.”
The difference shows in real output. Both scripts below print “Page starts” and “Page ends” around one line of old plugin code. With a deprecation notice the page is finished; with a fatal error, “Page ends” never comes:
wp-content/plugins/shop-cart/includes/class-cart-total.php
<?php
class Cart_Total {
public function __construct() {
$this->total = 42;
}
}
echo "Page starts\n";
$cart = new Cart_Total();
echo "Total: ", $cart->total, "\n";
echo "Page ends\n";
Page starts
Deprecated: Creation of dynamic property Cart_Total::$total is deprecated in /var/www/html/wp-content/plugins/shop-cart/includes/class-cart-total.php on line 4
Total: 42
Page endswp-content/plugins/shop-cart/includes/sorting.php
<?php
echo "Page starts\n";
$by_price = create_function('$a, $b', 'return $a - $b;');
echo "Page ends\n";
Page starts
Fatal error: Uncaught Error: Call to undefined function create_function() in /var/www/html/wp-content/plugins/shop-cart/includes/sorting.php:3
Stack trace:
#0 {main}
thrown in /var/www/html/wp-content/plugins/shop-cart/includes/sorting.php on line 3A check that reads the code before an upgrade tells the two apart the same way:
Where the messages show up in WordPress
wp-config.php decides what WordPress does with PHP messages:
WP_DEBUGoff, the normal setting for a live site: WordPress asks PHP to report fatal errors and warnings, but not notices or deprecation notices (WordPress 7.1.2 source). Whether a warning then appears on the page depends on your server’sdisplay_errorssetting.WP_DEBUGon: every message is reported. It appears on the page unlessWP_DEBUG_DISPLAYisfalse, and it is also written to a log file whenWP_DEBUG_LOGis set (developer.wordpress.org).
WordPress switches displaying off by itself during its AJAX, REST API and XML-RPC requests (WordPress 7.1.2 source), so messages from those only reach the log. Normal pages and form submissions don’t get that protection.
How to hide deprecated warnings from visitors
First, is your site actually broken? If it shows WordPress’s critical-error message or a blank page, or something stops working (a form, the checkout, the admin area), there is a fatal error. Hiding messages won’t bring anything back, and it hides the one clue you have. Go to “There has been a critical error” after a PHP update instead.
If the site works and visitors see lines starting with “Deprecated:”, “Notice:” or “Warning:”, the site is set to display PHP messages. That should never be the case on a live site. php.net says of displaying errors: “This is a feature to support your development and should never be used on production systems (e.g. systems connected to the internet).” (php.net) The WordPress documentation agrees: “It is not recommended to use WP_DEBUG or the other debug tools on live sites; they are meant for local testing and staging installs.” (developer.wordpress.org)
- Open
wp-config.php(help below). - Use the normal live setting:
define( 'WP_DEBUG', false );. WordPress then doesn’t ask PHP to report deprecation notices at all. - Want a record while you track down the cause? Use the lines below instead: messages go to a log file, and nothing is shown on the page.
- Messages still visible? Then your server itself displays PHP messages, or a plugin changes the setting. Ask your host to switch
display_errorsoff for your site. - Reload a few pages and check they’re clean.
New to wp-config.php? How to edit it safely
- Make a copy first. Download the file, or duplicate it, so you can put it back if something goes wrong.
- Open the file. In your hosting control panel, open the File Manager and go to your WordPress folder (often called
public_html).wp-config.phpis usually there, next to thewp-adminandwp-contentfolders. You can also use an FTP program with the FTP details your host gives you. - Find the right place. Add new lines above the line
/* That's all, stop editing! Happy publishing. */(on older sites it ends with “Happy blogging”). If a line with the same name is already there, for exampledefine( 'WP_DEBUG', false );, change that line instead of adding a second one. - Save, then reload your site. If it shows an error, put your copy back.
Not comfortable doing this? Ask your host’s support to make the change; it’s a routine request.
These are the logging lines from the WordPress documentation, with the log file moved out of the public web folder, which the documentation allows. Ask your host for the right folder, and remove the lines when you’re done. We tested them on WordPress 7.1.2 with PHP 8.5: the pages stayed clean and the notices went to the log file.
wp-config.php · configuration from the WordPress documentation, tested on WordPress 7.1.2
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/home/your-account/logs/wp-errors.log' );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );Don’t switch error reporting off completely (for example with error_reporting( 0 );). It hides fatal errors from the log too, and the day something breaks you have no message to go on.
Hiding doesn’t fix anything
A hidden notice is still there: the plugin keeps doing the deprecated thing, and a later PHP version can turn it into an error. For dynamic properties, deprecated since PHP 8.2, the accepted plan is exactly that for PHP 9.0. And create_function() shows how it ends: deprecated in PHP 7.2, removed in PHP 8.0, where every call became a fatal error.
Deprecation notices announce what future PHP versions are expected to change. Fix them in the normal update cycle, before the PHP upgrade that needs them, not in a hurry after it.
Why messages on the page can break a working site
Before a page, PHP sends headers: instructions for the browser, such as “go to the thank-you page”. Once any text has been printed, including a PHP message, headers can no longer be sent. This contact form plugin works on PHP 8.1. On PHP 8.5 its deprecation notice is printed first, so the redirect fails and the visitor sees the messages instead of the thank-you page:
wp-content/plugins/contact-box/contact-box.php
<?php
class Contact_Form {
public function __construct() {
$this->sent = true;
}
}
$form = new Contact_Form();
// After sending, the plugin sends the visitor to a thank-you page
// (WordPress's wp_redirect() does this with the same header):
header('Location: /thank-you/');
echo "Form sent\n";
Form sentDeprecated: Creation of dynamic property Contact_Form::$sent is deprecated in /var/www/html/wp-content/plugins/contact-box/contact-box.php on line 4
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/plugins/contact-box/contact-box.php:4) in /var/www/html/wp-content/plugins/contact-box/contact-box.php on line 11
Form sentNothing in the plugin changed except the PHP version. We saw the same in WordPress 7.1.2 on PHP 8.5, with a test plugin that creates a dynamic property and then calls wp_redirect(): with messages displayed, there was no redirect (HTTP 200, two “headers already sent” warnings); with messages logged instead, the redirect worked.
Find the source
- Read the message: the folder after
wp-content/plugins/orwp-content/themes/names the plugin or theme. - Update it (Dashboard → Updates). Its developer may already have fixed the notice.
- Already on the latest version? Send the full message to its developer.
- Before your next PHP upgrade, check all plugins and themes at once. Reading the report shows how the check sorts them into “Will break” and “Deprecation notice”.
A check that reads code finds deprecated and removed features before you upgrade. It can’t see messages that depend on the values a plugin works with while it runs, so keep the log on for a few days after switching.
Key takeaways
- A fatal error stops the page. With a warning, a notice or a deprecation notice the page is still built; the message reports a problem now, a possible mistake, or a change needed before a future PHP version.
- On a live site, visitors should see none of them: keep
WP_DEBUGoff, or write messages to a log withWP_DEBUG_DISPLAYoff. - Messages shown on the page can break things that otherwise work, such as the redirect after a form is sent.
- Hiding changes nothing in the code: the plugin behind the message still needs an update or a fix before the PHP version that changes the feature.
- If the site shows a critical error or a blank page, or something stops working, don’t hide messages: find the fatal error.
Frequently asked questions
Can I just hide deprecated warnings?
Yes, and on a live site you should: visitors shouldn’t see them. Keep WP_DEBUG off, or write messages to a log with WP_DEBUG_DISPLAY off, as shown above. But hiding isn’t fixing: the plugin still uses something PHP plans to change, so update it or tell its developer. And never hide messages to make a broken site look quiet: the fatal error is your clue.
Do deprecation notices slow my site?
Each reported notice adds a little work: PHP writes it to the log, or onto the page. A few don’t matter; thousands per page view fill the log and add work to every request. With WP_DEBUG off, WordPress doesn’t ask PHP to report deprecation notices at all.
Why do notices appear after a PHP upgrade?
Each PHP version deprecates things that older versions accepted without a word. Code written for the old version keeps working but now gets a notice. One you may already know is new in PHP 8.2: “Creation of dynamic property … is deprecated”.
Is a warning dangerous?
A warning means something went wrong while the page was built, but PHP carried on: php.net calls warnings “Run-time warnings (non-fatal errors).” (php.net) Part of the page may be missing, for example text from a file that couldn’t be read. Check which plugin it comes from and report it to its developer.
Check your own site before you upgrade
CompatNav is a free WordPress plugin. It reads the code of your plugins and themes on your own server and tells you, in plain words, what will break and what will only show notices on the PHP version you choose. It never changes your code. It can’t see problems that only appear while code runs with real data, so a quick check of your site after the upgrade still matters.
Sources
- php.net: Predefined error constants (what each level means)
- php.net: Runtime configuration of errors (display_errors)
- developer.wordpress.org: Debugging in WordPress
- WordPress 7.1.2 source: wp_debug_mode()
About the code examples: each output is the real output of the code shown, run with the official PHP builds, without a php.ini, with all errors reported and displayed. Only the file path was replaced by a neutral server path.