A PHP update sounds simple in theory: flip the version in the hosting panel, do a quick test, done. In practice it often looks very different - especially for websites that ran on PHP 7.4 for years and then have to migrate straight to PHP 8.4 in one go. What starts as a routine maintenance task quickly turns into a tour through outdated theme code, incompatible plugins, and broken special characters in the database.
In this post, I’ll walk through a recently completed project to show which problems realistically come up during a WordPress PHP 8 migration, how a clean staging setup makes the difference, and why the X Theme by Themeco isn’t to blame, but is often where the troubleshooting trail starts.
Why WordPress PHP 8 migration is no longer something to put off in 2026
PHP 7.4 reached its official end-of-life back in November 2022 - no security updates since then. Many websites still run on it anyway, because “the update broke something once” or because nobody wants to touch it. The problem: every month on an outdated PHP version is a month of open security vulnerabilities and ever-growing technical debt.
Then there’s performance. PHP 8.x is up to three times faster than PHP 7.4, depending on the use case. On a typical WordPress site with many plugins, you’ll notice it immediately in time-to-first-byte and Core Web Vitals. And a lot has changed in type checking since PHP 8.0: 8.0 introduced strict type checks for internal functions, 8.1 deprecated many nullable-parameter patterns, 8.2 banned dynamic properties, and 8.4 tightened null-handling further. Every one of these steps creates breaking points in old plugin and theme code.
Starting right: staging instead of live-server roulette
The first rule for any WordPress PHP 8 migration: never go straight to production. That sounds obvious, but it still gets ignored often - usually with the argument “I have a backup.” A backup saves you if the site goes white. It doesn’t save you from cumulative problems you only notice after hours of clicking through the site.
Sorting out staging licensing with the X Theme: With the X Theme by Themeco, the staging setup is handled cleanly on the licensing side. Every single-use license allows one additional staging domain at no extra cost - provided it’s the same website, e.g. staging.domain.com for domain.com. The staging domain has to be validated in the Themeco account dashboard via the “Add Staging” button.
Setting up the staging clone: The staging environment itself is a full clone of the live site - files mirrored via SFTP or SSH, database taken over via mysqldump, URLs adjusted via wp search-replace or a clean SQL query.
The first surprise: MySQLi charset errors
Right after cloning to staging, the first error appeared - before the actual PHP update even started. A mysqli_sql_exception combined with a charset issue. Cause: the new server used utf8mb4 as its default, while the database from the old environment still had utf8mb3 lurking in many places.
The fix: DB_CHARSET in wp-config.php was switched from utf8mb3 to utf8mb4, and hosting support migrated MySQL server-side to utf8mb4_unicode_ci.
The actual PHP jump: from 7.4 to 8.4
Error 1 - child theme calling a deprecated API: An old customization used the deprecated clean_url filter, which no longer runs cleanly under PHP 8.4. On top of that, script loading was set up in a way that broke the WordPress core loading order.
The fix: replaced the deprecated clean_url filter with the modern script_loader_tag filter - and deliberately used a whitelist instead of a blacklist.
The “The Grid” plugin - when floor() becomes a fatal error
The “The Grid” plugin threw a fatal error in the-grid-base.class.php, line 603:
$whole = floor($n_format);
Since PHP 8.0, floor() strictly requires a numeric value. The plugin was passing a string at this point. Fix:
$whole = floor((float) $n_format);
WPML and UberMenu - when old versions collide
WPML threw fatal errors. The cause was an old WPML version with an -old suffix that had been left behind in the plugin directory and was being loaded alongside the current one. Two versions of the same plugin active at once: guaranteed chaos.
UberMenu had its own issue: hover events stopped working. Fix: switch to event delegation via $(document).on().
Font Awesome and small frontend leftovers
After the theme and plugin updates, the search icon was missing. Fix via CSS in the child theme:
.x-btn-navbar-search .x-icon-search:before { font-family: "Font Awesome 5 Free"; content: "\f002"; }
The final boss: broken special characters from charset chaos
After all the updates, entries like these showed up in the database (German-language content in this project):
Über unsinstead ofÜber unsBluetooth® Lautsprecherinstead ofBluetooth® LautsprecherFlächeinstead ofFläche
This is the classic symptom of a double encoding conversion (mojibake).
Encoding cleanup - what works and what doesn’t
The robust approach was a combination:
- For
wp_posts,wp_terms, andwp_comments: explicitREPLACE()chains via SQL - For serialized tables: a custom PHP script using
maybe_unserialize()/maybe_serialize()
Example of a REPLACE() chain:
UPDATE wp_posts SET post_title = REPLACE(REPLACE(REPLACE(post_title, 'ü', 'ü'), 'ö', 'ö'), 'Ü', 'Ü');
Important: never touch
wp_optionsorwp_postmetawith direct string conversion.
The invisible wins after migration
- Server response time dropped noticeably
- Memory usage per request went down
- Core Web Vitals improved
- Security updates started arriving regularly again
Checklist for your own WordPress PHP 8 migration
- Take stock - which PHP version is running? Which plugins and themes are installed?
- Set up staging - a clean copy of the live site with identical server configuration
- Check database and charset - make sure
utf8mb4is used consistently - Set up backups - complete, automated, stored off-site
- Step up the PHP version gradually - not straight from 7.4 to 8.4, but tested through 8.0, 8.1, 8.2
- Update plugins and theme - critical ones first, then the rest; test every update individually
- Clean up encoding - fix typical mojibake patterns with
REPLACE()statements - Click through the frontend - manually check every important page
- Enable performance and error monitoring - watch the logs for at least two weeks
Conclusion
A WordPress PHP 8 migration is only a technical version change on paper. In practice, it’s an honest look at the state of your WordPress installation. With the right order - staging before live, database before PHP, PHP before theme, everything before encoding - even a WordPress site neglected for years can land cleanly on PHP 8.4.


