Wordpress: PHP parse errors not logged due to error_reporting value

Created on 2 Aug 2019  路  5Comments  路  Source: docker-library/wordpress

What happened vs what I expected

I ran WordPress based on the wordpress:5.2.2-php7.3-apache image. I updated a page template and visited the page in a browser. I got an HTTP 500 "Internal Server Error". I expected to be able to see the error as logged to the Apache error log, which for this image goes to the docker log. There was no error in the log.

Why

It turns out that the HTTP 500 error was caused by a PHP parse error. Parse errors aren't included in the error logging because of this entry in /usr/local/etc/php/conf.d/error-logging.ini:
error_reporting = 4339

That integer value has a 0 in the bit for reporting parse errors. It would need to be changed to 4343 in order to have PHP parse errors included in the error log. Changing error_reporting to 4343 and restarting made it so that I could see the parse errors in the logs. Ideally this value wouldn't be set as a number at all, since PHP supports using expressions. The following value is in php.ini-production and might be a better choice: E_ALL & ~E_DEPRECATED & ~E_STRICT

Problems

I see a few problems with the current situation.
1) The error_reporting value in /usr/local/etc/php/conf.d/error-logging.ini is a number. It should be an expression so it is easier to read.
2) The error_reporting value in /usr/local/etc/php/conf.d/error-logging.ini doesn't include parse errors. I can't think of a reason why you would want to exclude parse errors.
3) If I copy php.ini-production to php.ini, which is recommended for a production site, then the error_reporting value is set in two places, and the one from php.ini is overridden by error-logging.ini. I did not expect this and it was hard for me to hunt down. I assume others may have the same problem.

Steps to reproduce

mkdir missing_parse_error
cd missing_parse_error
# create Docker file from the wordpress image
cat > Dockerfile <<'EOF'
FROM wordpress:5.2.2-php7.3-apache
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
RUN echo "this line causes an intentional parse error" >> /usr/src/wordpress/index.php
EOF

#create docker-compose file
cat > docker-compose.yml <<'EOF'
version: '3'
services:
  wordpress:
    build: "."
    ports:
     - "80:80"
    environment:
      WORDPRESS_DB_HOST: "mysql"
      WORDPRESS_DB_USER: "root"
      WORDPRESS_DB_PASSWORD: "password"
      WORDPRESS_DB_NAME: "wordpress"
  mysql:
    image: "mysql/mysql-server:5.7.27"
    environment:
      MYSQL_ROOT_HOST: "%"
      MYSQL_ROOT_PASSWORD: "password"
EOF
docker-compose build
docker-compose up -d
#run a request that will trigger a 500 error (You may have to wait while the containers start)
curl -v http://127.0.0.1
# output the logs and see that there is no parse error logged
docker-compose logs wordpress

#update the Dockerfile to add a different value in error-logging.ini
cat >> Dockerfile <<'EOF'
RUN sed -i -e 's/^error_reporting .*/error_reporting = E_ALL \& ~E_DEPRECATED \& ~E_STRICT/' /usr/local/etc/php/conf.d/error-logging.ini
EOF
docker-compose build
docker-compose up -d
#run a request that will trigger a 500 error 
curl -v http://127.0.0.1
# output the logs and see that there is a parse error now
docker-compose logs wordpress

Possible solutions

1) Change the error-logging.ini value to 4343 so parse errors are logged
2) Change the error-logging.ini value so it includes parser errors and is also readable, such as E_ALL & ~E_DEPRECATED & ~E_STRICT
3) Rearrange the configuration such that the value of error_reporting in php.ini isn't overridden. This may involve having a default php.ini.

All 5 comments

We use the Sample recommended php.ini error settings:

error_reporting = 4339
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /home/example.com/logs/php_error.log
log_errors_max_len = 1024
ignore_repeated_errors = On
ignore_repeated_source = Off
html_errors = Off

https://wordpress.org/support/article/editing-wp-config-php/#configure-error-logging

About Error Reporting 4339 This is a custom value that only logs issues that affect the functioning of your site, and ignores things like notices that may not even be errors. See PHP Error Constants for the meaning of each binary position for 1000011110011, which is the binary number equal to 4339. The far left 1 means report any E_RECOVERABLE_ERROR. The next 0 means do not report E_STRICT, (which is thrown when sloppy but functional coding is used) and so on. Feel free to determine your own custom error reporting number to use in place of 4339.

Feel free to determine your own custom error reporting number to use in place of 4339.

I believe it would be best to modify this value to not hide a potential cause of a HTTP 500 error. If others disagree and think it best to hide PHP parser errors then that's fine, although I'd like to know why.

My intent is for others to not have to go through the same troubles as I did to hunt down the reason why my error is never logged.

I guess combining "Feel free to determine your own custom error reporting number to use in place of 4339." with the fact that we explicitly set logs to go to the Docker logs and never the browser (https://github.com/docker-library/wordpress/blob/fc7f07cb8bd12b4f4a8d30710348af0445ce46af/Dockerfile-debian.template#L57) leads me to think this should be reasonable. I like the suggestion of using the semantic value instead of a raw numeric (we kept the raw numeric simply to keep our value exactly in line with what's published by the WordPress upstream project as the recommended value).

So, just for completeness, the full set of errors their suggested value includes is:

  • E_ERROR
  • E_WARNING
  • E_CORE_ERROR
  • E_CORE_WARNING
  • E_COMPILE_ERROR
  • E_COMPILE_WARNING
  • E_RECOVERABLE_ERROR

Which means the full set of things they exclude is:

  • E_PARSE
  • E_NOTICE
  • E_USER_ERROR
  • E_USER_WARNING
  • E_USER_NOTICE
  • E_STRICT
  • E_DEPRECATED
  • E_USER_DEPRECATED

(Not an argument for or against, but I wanted to have an explicit full list of the interpreted current value for posterity; values from https://www.php.net/manual/en/errorfunc.constants.php)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bckelley picture bckelley  路  4Comments

verygoodsoftwarenotvirus picture verygoodsoftwarenotvirus  路  5Comments

chrissound picture chrissound  路  5Comments

TeachMeHowToUse2FA picture TeachMeHowToUse2FA  路  4Comments

darkl0rd picture darkl0rd  路  5Comments