Wordpress Logo

WordPress: Changing error_reporting level

Posted by

Warning for PHP >= 8.0 Users

Per the comment from Alexey below, PHP 8.0 changes the behaviour of disable_functions to make disabled functions undefined, thus creating a fatal error. You can probably define a basic function error_reporting() which just returns true, in wp_config.php, but I haven’t tried this.

The Disclaimer…

Don’t get me wrong. I like WordPress as a product. It does a job and it does it fairly well. But here endeth the praise.

The Rant…

WordPress’s codebase is, to put it politely, a fucking shit-show. In the codebase of this very blog you’re reading now, there are no fewer than 46 references to error_reporting across WordPress core and plugins.

By default, WordPress will log the following, unless of course a plugin or some other voodoo-magic changes it:

E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR

What’s slightly annoying about this is the fact it logs warnings. Given the aforementioned shit-show-ness of the WordPress code base and the plugins that attach to it, it tends to log a fair few warnings, thus flooding your log files with junk

There doesn’t seem to be a nice way to change this, without hacking WordPress’s core code. You can add a call to error_reporting() in wp-config.php but it gets overridden some time later during WP loading. You can create a plugin which changes it but some other plugin is inevitably going to change it back again and it’s already logged core warnings by this point.

The Solution…

PHP has a disable_functions setting. Do you see where I’m going with this? 😉

If you add error_reporting to the end of the list of the disable_functions setting in your php.ini then WordPress can no longer change error_reporting settings and, thus, the setting provided in your php.ini will be honoured.

The big downside of this is that if you’re running something other than WordPress on your server, it also cannot do error_reporting(). This probably isn’t a big deal because changing error reporting levels at runtime is, frankly, fucking annoying. If, for whatever reason you do need to do this, you could create a separate php-fpm pool for WordPress and pass the modified disable_functions value to that pool like so:

php_admin_value[disable_functions] = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,error_reporting,

The other possible downside is that there may be a scenario where WordPress’s changing of error_reporting is useful. I’m not sure what this is but I’m imagining a scenario where loading a plugin throws an error and it can catch this and display it to you in the wp-admin UI. If this were the case (I’ll update this blog post if ever I find it to be…) then you can create a separate FPM pool for /wp-admin/* and not disable error_reporting there. If you were to do this, you should remember that /wp-admin/admin-ajax.php can be called by plugins on the main site and isn’t actually anything to do with the administration of your site (did I say how much of a shit-show WordPress is?) so you need to assign this file to the main pool and not the pool of your /wp-admin/*.

Clear? Cool. Enjoy <3

6 comments

  1. Adding error_reporting to disable_functions will cause scripts to emit
    Warning: error_reporting() has been disabled for security reasons in PHP 7.4
    and
    Fatal error: Uncaught Error: Call to undefined function error_reporting() in PHP 8.0

    1. The warning I was aware of though it would be suppressed as the need for changing the error_reporting level in WordPress is to stop it spamming logs with warning.

      The 8.0 fatal error is news to me – thank you! I’m glad PHP are sticking with the tradition of royally fucking backwards compatibility in every version 😀 From what I can see, WordPress core acknowledged this 12 or so months ago and have added some function_exists() checks. I’ll add a note to this post, though.

  2. I came across your post when I was looking for a solution to fix the messed up situation of WordPress messing with my error settings. It can make debugging painful for sure.

    I’ve found that using the method listed in load.php seems to work pretty well. I put the code below in wp-config right before settings.php is called.

    //
    // Taken from wp-includes/load.php
    // Disables having WordPress mess with debug functions
    // This way, the debug setting sticks and doesn’t suck
    //

    $GLOBALS[‘wp_filter’] = array(
    ‘enable_wp_debug_mode_checks’ => array(
    10 => array(
    array(
    ‘accepted_args’ => 0,
    ‘function’ => function() {
    return false;
    },
    ),
    ),
    ),
    );

    I can set the error reporting level at the top of wp-config (before settings.php is called) and it seems to stick. It will respect your php.ini setting as well. Did you try this method?

    1. I did but, in my case, some equally-crappy plugins directly called error_reporting() and changed the setting back. Disabling error_reporting() completely was the most reliable way I found to stop things fiddling with it.

  3. Will throw in a fix that seemed to worked for me so far:

    I run WP sites in using simple docker-compose that looks like this:

    services:
    app:
    image: richarvey/nginx-php-fpm:3.1.6
    restart: always
    logging:
    driver: “json-file”
    options:
    max-size: “50m”
    max-file: “5”
    ports:
    – “80:80”
    – “443:443”
    volumes:
    – .conf/nginx/sites-enabled:/etc/nginx/sites-enabled
    – .:/usr/share/nginx/html
    – .conf/php/custom.ini:/usr/local/etc/php/conf.d/custom.ini
    – /etc/letsencrypt:/etc/letsencrypt
    depends_on:
    – db

    Specifically note this part of the volume config

    – .conf/php/custom.ini:/usr/local/etc/php/conf.d/custom.ini

    We are basically injecting custom.ini file located inside of our WP project .conf folder to the running container that looks like this:

    error_reporting=E_ALL & ~E_DEPRECATED & ~E_STRICT
    disable_functions=error_reporting

    Now, just like other people mentioned in the comments PHP 8 will throw in Call to undefined function error_reporting() ( until WordPress core team will add function exists checks at least ), but we can just add dummy error_reporting function to the top of wp-config.php

    // Since we disable error_repring in php.ini
    // we have to define dummy function here to avoid breakage
    function error_reporting() {}

    And that’s about it. We can control error reporting level in using .ini config without breaking WordPress.

    Hope that helps someone else and thanks for the original idea of disabling error_reporting Phil.

Leave a Reply

Your email address will not be published. Required fields are marked *