Fatal errors on WordPress with PHP 8+ and an incorrect translation

Last week, I got a report about a broken site, that caught me a bit by surprise. I’ll recreate the issue with a dummy plugin here, so show what went wrong. When navigating to the page with the error, this message was presented to me:

Fatal error: Uncaught Error: Missing format specifier at end of string
in /var/www/html/wp-content/plugins/broken-format-string/broken-format-string.php on line 15

I looked at the code and saw something like:

printf(
	__( 'Publish date: %s', 'broken-format-string' ),
	date_i18n( get_option( 'date_format' ), get_post_datetime() )
);

Nothing fancy so far. Just a format string with a placeholder for a string, that gets replaced with the post date in the WordPress date format.

Incorrect translation

As I couldn’t see any issue here, I was first a bit confused, what the issue would be. But since the website language was not set to “English (US)”, I’ve checked the translation file. Again, here is an example of a translation with a similar issue:

#: broken-format-string.php:14
msgid "Publish date: %s"
msgstr "Veröffentlichungsdatum: %"

This German translation is translating the “Publish date:” part, but as the placeholder, it is only using a % instead of a %s and this causes the issue. WordPress would translate the original string to German and then pass it to the printf() function, which then exists with a “Fatal error”.

Different error handing with PHP 8+

When you run this code with PHP 7.4 and earlier, you don’t get a fatal error. You don’t even get a PHP notice or warning. It would just not replace the placeholder correctly. The % would just be replaced with an empty string. But as soon as you upgrade to PHP 8+ you will have a broken site.

This was one of the first real issues I have recognized with PHP 8+ on a WordPress site. Maybe I was just lucky, or translation always had all the placeholders translated correctly.

Conclusion

I’ve done some checks for PHP 8+ compatibility with the PHPCompatibilityWP and so far it never failed me. But I would never have imagined, that an incorrect translation would cause a fatal error. When translations are made with GlotPress (used on translate.wordpress.org), you will see a warning, that the translation is missing a placeholder. But tools like Poedit don’t show such a warning. So when you have someone translating a plugin/theme into a language you don’t speak, better make sure that format strings are correct.

Posted by

Bernhard is a full time web developer who likes to write WordPress plugins in his free time and is an active member of the WP Meetups in Berlin and Potsdam.

Leave a Reply

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