Heb je WordPress bijgewerkt naar WordPress 7.1 en krijg je ineens een wit scherm of de melding “Er heeft zich een kritieke fout voorgedaan op deze website”? Dan kan WP Rocket de boosdoener zijn.
Na de release van WordPress 7.1 blijkt er een compatibiliteitsprobleem te zijn met WP Rocket. Het vervelende is dat de fout niet alleen de voorkant van de website platlegt. Ook wp-admin, de REST API, admin-ajax en zelfs WP-CLI kunnen hierdoor niet meer werken.
Gelukkig is de website vrij eenvoudig weer online te krijgen.
Welke foutmelding krijg je?
In de PHP error log van de server verschijnt onder andere de volgende fout:
PHP Fatal error: Uncaught TypeError:
substr(): Argument #1 ($string) must be of type string, int given
Daarbij wordt verwezen naar:
wp-content/plugins/wp-rocket/inc/ThirdParty/Plugins/CDN/Cloudflare.php
en specifiek naar regel 562.
Zie je deze combinatie na een update naar WordPress 7.1? Dan is de kans groot dat je tegen deze bug in WP Rocket aanloopt.
Oplossing 1: tijdelijke fix via een MU-plugin
Er is een tijdelijke fix beschikbaar waarmee je WP Rocket actief kunt houden. De oplossing wordt als een klein PHP-bestand in de map mu-plugins geplaatst.
Een MU-plugin (Must Use Plugin) wordt automatisch door WordPress geladen. Je hoeft deze dus niet via wp-admin te activeren.
Stap 1: download het fix-bestand: wp-rocket-cloudflare-intkey-fix.php
Het bestand kan in je browser als platte tekst worden geopend. Klik in dat geval met de rechtermuisknop op de pagina en kies ‘Opslaan als’.
Sla het bestand exact op als:
wp-rocket-cloudflare-intkey-fix.php
Laat het bestand als één .php-bestand staan. Je hoeft het dus niet in een ZIP-bestand te plaatsen.
Stap 2: maak verbinding met je website
Maak via SFTP verbinding met je website of gebruik de File Manager van je hostingprovider.
Ga vervolgens naar:
/wp-content/
Stap 3: controleer de map mu-plugins
Controleer of binnen wp-content een map met de volgende naam bestaat:
mu-plugins
Bestaat deze map nog niet? Maak hem dan zelf aan.
Let erop dat de map exact deze naam krijgt:
/wp-content/mu-plugins/
Stap 4: upload het fix-bestand
Upload:
wp-rocket-cloudflare-intkey-fix.php
rechtstreeks naar:
/wp-content/mu-plugins/
Het uiteindelijke pad moet dus zijn:
/wp-content/mu-plugins/wp-rocket-cloudflare-intkey-fix.php
Plaats het bestand niet in een extra submap.
Stap 5: herlaad je website
Herlaad nu de website.
Als de fout inderdaad wordt veroorzaakt door deze WP Rocket/WordPress 7.1 incompatibiliteit, zou de kritieke fout direct verdwenen moeten zijn.
Het voordeel van deze methode is dat je WP Rocket niet volledig hoeft uit te schakelen.
Belangrijk: zie dit als een tijdelijke workaround. Zodra WP Rocket een officiële update heeft uitgebracht waarin het probleem is opgelost, is het verstandig de plugin te updaten en te controleren of deze MU-plugin nog nodig is.
Oplossing 2: WP Rocket volledig uitschakelen
Wil je geen tijdelijke PHP-fix gebruiken? Dan kun je WP Rocket ook volledig uitschakelen.
Dat klinkt simpel, maar er is een probleem: doordat de fout tijdens het opstarten van WordPress optreedt, kun je meestal ook niet meer inloggen op /wp-admin/.
Je zult WP Rocket daarom buiten WordPress om moeten uitschakelen.
Via FTP of SFTP
Maak via FTP/SFTP verbinding met de server en ga naar:
/wp-content/plugins/
Zoek vervolgens de map:
wp-rocket
en hernoem deze bijvoorbeeld naar:
wp-rocket-disabled
WordPress kan de plugin vervolgens niet meer laden en zal WP Rocket automatisch als gedeactiveerd beschouwen.
Herlaad daarna de website. In de meeste gevallen werkt de site direct weer.
Via WP-CLI
Heb je SSH-toegang tot de server? Dan kun je WP Rocket ook via WP-CLI uitschakelen.
Een normale:
wp plugin deactivate wp-rocket
kan echter óók crashen, omdat WP-CLI WordPress en de actieve plugins probeert te laden.
Gebruik daarom:
wp plugin deactivate wp-rocket --skip-plugins=wp-rocket
Hiermee vertel je WP-CLI dat WP Rocket tijdens het uitvoeren van het commando niet geladen moet worden.
Verwijder niet zomaar Cloudflare.php
Omdat de foutmelding naar Cloudflare.php verwijst, kan het verleidelijk zijn om dit bestand uit WP Rocket te verwijderen of aan te passen.
Doe dit liever niet.
Het bestand maakt onderdeel uit van WP Rocket en simpelweg verwijderen kan weer andere fatale fouten veroorzaken.
Gebruik liever de tijdelijke MU-plugin hierboven of schakel WP Rocket volledig uit.
Maar ik gebruik helemaal geen Cloudflare?
Opvallend genoeg hoef je Cloudflare niet daadwerkelijk te gebruiken om tegen deze fout aan te lopen.
De betreffende Cloudflare-compatibiliteitscode van WP Rocket kan namelijk worden uitgevoerd zonder dat je zelf Cloudflare hebt gekoppeld.
Een verwijzing naar Cloudflare.php in de foutmelding betekent dus niet automatisch dat het probleem bij Cloudflare ligt.
Wat veroorzaakt de fout?
De oorzaak zit in een wijziging in WordPress 7.1 in de manier waarop WordPress unieke ID’s voor callbacks van hooks opbouwt.
Tot en met WordPress 7.0.x werd hiervoor bij objecten onder andere spl_object_hash() gebruikt. Dat leverde een lange tekenreeks op.
WordPress 7.1 gebruikt hiervoor spl_object_id(). Dit resulteert in een numerieke waarde.
Hoewel WordPress de waarde als string teruggeeft, kan PHP een numerieke string die als array-key wordt gebruikt automatisch omzetten naar een integer.
WP Rocket gaat er in de betreffende Cloudflare-code echter vanuit dat deze keys altijd strings zijn.
Vervolgens wordt ongeveer het volgende uitgevoerd:
substr( $key, - strlen( $method ) )
Wanneer $key inmiddels een integer is, gaat dat mis.
Omdat het betreffende WP Rocket-bestand met strict typing werkt, weigert PHP de integer automatisch naar een string om te zetten.
Het resultaat:
TypeError: substr(): Argument #1 ($string) must be of type string, int given
Omdat dit al tijdens het initialiseren van WordPress gebeurt, kan vervolgens praktisch de hele WordPress-installatie eruit liggen.
Wanneer treedt het probleem op?
Niet iedere WordPress 7.1-website met WP Rocket hoeft automatisch te crashen.
De combinatie ontstaat wanneer onder andere:
- WordPress 7.1 wordt gebruikt;
- WP Rocket actief is;
- een plugin of theme een bepaalde closure aan een WordPress-hook koppelt;
- WP Rocket deze callback vervolgens probeert te verwerken.
Een plugin die de situatie kan triggeren is bijvoorbeeld Elementor Pro.
Dat betekent overigens niet dat Elementor Pro iets verkeerd doet. Het gebruik van closures binnen WordPress-hooks is normaal. Het probleem zit in de aanname die WP Rocket maakt over het datatype van de callback-ID.
Nog niet bijgewerkt naar WordPress 7.1?
Gebruik je WP Rocket en draait je website nog op WordPress 7.0.x?
Dan kan het verstandig zijn om nog even te wachten met de update naar WordPress 7.1 totdat WP Rocket een versie heeft uitgebracht waarin het probleem officieel is opgelost.
Controleer daarbij ook of automatische WordPress core-updates ingeschakeld zijn.
Kan ik WordPress terugzetten naar 7.0.4?
Ja. Het terugzetten van een backup of downgraden naar WordPress 7.0.4 kan het probleem eveneens oplossen.
In de meeste gevallen is dat echter niet nodig.
Gebruik eerst de tijdelijke MU-plugin of schakel WP Rocket uit. Dat heeft doorgaans minder impact dan het downgraden van de volledige WordPress-installatie.
Conclusie
Krijg je na de update naar WordPress 7.1 een fatale PHP-fout met:
substr(): Argument #1 ($string) must be of type string, int given
en verwijst de stacktrace naar:
wp-rocket/inc/ThirdParty/Plugins/CDN/Cloudflare.php
dan is WP Rocket waarschijnlijk de oorzaak.
De voorkeursoplossing is om de tijdelijke wp-rocket-cloudflare-intkey-fix.php als MU-plugin te plaatsen:
/wp-content/mu-plugins/wp-rocket-cloudflare-intkey-fix.php
Hierdoor kun je WP Rocket actief houden terwijl de fout wordt omzeild.
Lukt dat niet, dan kun je WP Rocket tijdelijk volledig uitschakelen via SFTP of WP-CLI.
Zodra WP Rocket met een officiële oplossing komt, update je WP Rocket en kun je de tijdelijke fix na controle weer verwijderen.
Tip: maak voordat je grote WordPress-, plugin- of PHP-updates uitvoert altijd eerst een backup en test belangrijke updates indien mogelijk op een stagingomgeving. Dat voorkomt dat een onverwachte incompatibiliteit direct je live website platlegt.