Een typische foutmelding ziet er zo uit:
Fatal error: Uncaught ArgumentCountError:
Too few arguments to function My_Widget::__construct(),
0 passed in /wp-includes/class-wp-widget-factory.php on line 65
and exactly 1 expected
in /wp-content/plugins/my-plugin/widgets/My_Widget.php:24
Drie cruciale stukken informatie hieruit:
- De aangeroepen functie:
My_Widget::__construct()— een widget-constructor. - Hoeveel argumenten waren verwacht en gegeven: 0 doorgegeven, 1 verwacht. Of in andere meldingen: "2 passed and exactly 3 expected".
- Beide bestand-paden:
wp-widget-factory.php:65is de plek die de aanroep doet (WordPress core);My_Widget.php:24is de plek die de signature heeft die niet matcht (jouw widget). De fix zit in de tweede, niet de eerste.
Waarom zie je dit nu pas? PHP 8 is de oorzaak.
Op PHP 7 kreeg je dezelfde situatie alleen een Warning:
Warning: Missing argument 1 for My_Widget::__construct()
Een waarschuwing — geen fatal. Het script ging gewoon door, vulde het ontbrekende argument met null, en je code draaide door. Vaak met subtiel kapot gedrag dat je nooit herkende, omdat de waarschuwing in de log verdween en de site bleef werken.
PHP 8 (uitgebracht november 2020) maakte dit een TypeError. Een fatal. Het script stopt direct. Dezelfde bug, andere reactie. Veel oudere WordPress-plugins, themes en custom code hadden deze bug al jaren — alleen niemand merkte het op PHP 7.
Plus PHP 8 voegde nog twee andere strict-checks toe die vergelijkbare meldingen kunnen geven: TypeError bij het meegeven van het verkeerde type, en ValueError bij ongeldige waarden. Too few arguments is de meest voorkomende.
De vier hoofd-scenario's
1. WordPress-widget met eigen constructor (#1 oorzaak)
De code die jij hierboven plakte komt rechtstreeks uit oude WordPress-widget-loading:
// In wp-includes/class-wp-widget-factory.php
$this->widgets[ $widget ] = new $widget( $widget, $widget );
WordPress geeft hier 2 argumenten mee aan de widget-constructor. De WP_Widget-base-class verwacht 4 (allemaal optioneel). Heb jij een widget met:
class My_Widget extends WP_Widget {
public function __construct( $required_arg ) { // VERPLICHT 1 ARG
parent::__construct( ... );
}
}
...dan crasht de widget-loader want WP geeft eigenlijk 2 args, of 0 in andere code-paden.
Fix: laat de constructor optioneel of volg de WordPress-conventie:
class My_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'my_widget', // Base ID
'Mijn Widget', // Naam in admin
array( 'description' => 'Een widget' ) // Opties
);
}
}
Of als je per se eigen args wilt:
class My_Widget extends WP_Widget {
// Maak de extra param optioneel
public function __construct( $extra_arg = null ) {
parent::__construct( 'my_widget', 'Mijn Widget' );
$this->extra_arg = $extra_arg;
}
}
2. Plugin- of theme-class met geupdate signature
Een base class is gewijzigd (vaak na een plugin-update), maar jouw extending class of een hook-callback is nog niet bijgewerkt. WooCommerce, ACF en grotere plugins doen dit met enige regelmaat — meestal compatible, soms niet.
Voorbeeld:
// Plugin update versie 5.0:
// abstract function process_payment( $order_id, $payment_method ); // 2 args
//
// Jouw oude code (versie <5.0):
class My_Payment_Gateway extends WC_Payment_Gateway {
public function process_payment( $order_id ) { ... } // 1 arg
}
Fix: bekijk de plugin-changelog en pas je override aan zodat de signatures matchen. Bij twijfel: maak alle extra args optioneel met defaults.
3. Hook-callback met te weinig accepted_args
WordPress' add_filter() en add_action() hebben een vierde parameter $accepted_args die default 1 is. Geef je dat niet correct op, dan krijgt je callback minder args dan z'n signature vereist:
// Verkeerd:
add_filter( 'the_title', 'my_callback' ); // accepted_args = 1 (default)
function my_callback( $title, $post_id ) { // VERPLICHT 2 ARGS
return $title;
}
// PHP 8 fatal: too few arguments
// Goed:
add_filter( 'the_title', 'my_callback', 10, 2 ); // priority 10, 2 args
Fix: tel hoeveel args je callback nodig heeft, geef die als 4e parameter aan add_action/add_filter. Of maak de extra args optioneel.
4. Custom code met namespace- of typo-issues
Eigen code waarbij iemand een methode heeft hernoemd of een nieuw verplicht argument heeft toegevoegd, en niet alle aanroep-locaties heeft bijgewerkt.
class Logger {
// Iemand voegde $level toe
public function log( $message, $level ) { ... }
}
// Op een andere plek in de code:
$logger->log( 'Foutje' ); // Crasht: te weinig args
Fix: $level = 'info' als default zodat oude aanroepen blijven werken. Of zoek alle aanroepen via grep -rn 'logger->log(' . en update ze allemaal.
Stappenplan: dit doe je nu
- Lees de exacte foutmelding. Welk bestand+regel toont de signature die niet matcht? Dat is de plek die je opent.
- Open het bestand en kijk naar de constructor of methode op die regel. Wat zijn de verplichte parameters?
- Maak de extra parameters optioneel met een default-waarde, of zorg dat de aanroep-zijde de juiste args meegeeft.
- Refresh de site. Fout weg? Klaar. Andere fout op een andere plek? Same drill.
Snel diagnose-trucje: PHP-versie checken
Weet je zeker dat 't door PHP 8 komt? Maak een info.php in je wp-root:
<?php phpinfo();
Open https://voorbeeld.nl/info.php en zoek naar "PHP Version". Versie 8.0 of hoger? Dan is dat de katalysator.
Verwijder dit bestand direct na de check — phpinfo lekt server-info naar het publiek.
De tijdelijke noodgreep: PHP 7 terugzetten
Als je geen tijd hebt voor een echte fix en de site moet draaien:
- cPanel: MultiPHP Manager → selecteer je domein → verander naar PHP 7.4
- DirectAdmin: PHP Selector → selecteer PHP 7.4
- Plesk: Hosting Settings → PHP → selecteer 7.4
Maar: PHP 7.4 ontvangt geen security-updates meer sinds eind 2022. Je hoster gaat 'm vroeg of laat uitschakelen, en dan is je site écht offline. Gebruik dit alleen als korte-termijn-noodgreep, en plan binnen weken een echte fix.
Lees: PHP-versie veilig upgraden zonder je site te slopen voor een gefaseerde aanpak.
De echte fix: plugins en themes bijwerken
Voor 90% van de gevallen is de echte oplossing simpel: update de plugin of theme die de fout veroorzaakt. Developers hebben hun code al jaren PHP 8-compatible gemaakt — maar oude versies bestaan natuurlijk nog.
Stappen:
- Identificeer het bestand uit de error-melding (vaak
wp-content/plugins/X/...) - Ga naar de plugin-pagina op wordpress.org of de developer-website
- Check of er een nieuwere versie is
- Backup, update, test
Geen update beschikbaar (plugin is verlaten)? Drie opties:
- Vervang door een actieve alternatief — vaak bestaan er moderne plugins die hetzelfde doen
- Fork de plugin en fix de specifieke regel zelf (handig voor developers)
- Schakel de plugin uit als de functie niet kritiek is
Veelgestelde vragen
Mijn site gaf eerst alleen een witte pagina, nu ineens deze melding — veranderd er iets?
WP_DEBUG werd waarschijnlijk aangezet (door jou of door een plugin). Met WP_DEBUG=true en WP_DEBUG_DISPLAY=true toont WordPress de PHP-fouten op het scherm; daarvoor zag je een witte pagina (server-foutmelding onderdrukt). Goed nieuws: nu kun je de oorzaak zien.
De error noemt geen plugin maar een theme-bestand — wat dan?
Dezelfde aanpak. Open het theme-bestand op de aangewezen regel, vergelijk de constructor- of methode-signature met hoe het wordt aangeroepen. Themes zijn vaker outdated dan plugins; check eerst of er een update is op je theme-leverancier-website.
Werkt dit ook bij Drupal of Joomla?
Ja. Too few arguments is een PHP-error, niet een WordPress-error. In Drupal zie je 'm vaak in custom modules of in oude contrib-modules na een PHP-upgrade. In Joomla idem in extensions. De fix is identiek: signatures matchen of args optioneel maken.
Kan ik PHP forceren om de oude PHP 7-gedrag te tonen (waarschuwing in plaats van fatal)?
Niet zonder source-code-aanpassing aan PHP zelf. Wel kun je in error-handlers de TypeError opvangen, maar dat is een pleister: de ontbrekende argument is alsnog null, dus het gedrag is alsnog onverwacht. Beter de echte fix.
Hoe voorkom ik dit bij toekomstige updates?
Drie maatregelen: (1) staging-omgeving vóór elke PHP-upgrade, (2) PHP-versie van plugins checken in hun documentatie vóórdat je activeert, (3) abonneer op plugin-changelog-feeds zodat je weet als 'breaking changes' op komst zijn.