“Optional parameter … declared before required parameter” in WordPress: what it means
Short answer
It’s a deprecation notice: a function in a plugin or theme gives a parameter a default value although a required parameter follows it, so the default can never be used. PHP 8.0 says “Required parameter … follows optional parameter …”; PHP 8.1 and later say “Optional parameter … declared before required parameter … is implicitly treated as a required parameter”. The code works exactly as before. The fix is to remove the default that was never used, in the plugin’s code.
The message on each PHP version
The same function in a shop plugin, on PHP 7.4, 8.0, 8.1 and 8.4:
wp-content/plugins/shop-helper/includes/prices.php
<?php
function format_price($currency = 'EUR', $amount) {
return number_format($amount, 2) . ' ' . $currency;
}
echo format_price('USD', 5), "\n";
5.00 USDDeprecated: Required parameter $amount follows optional parameter $currency in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2
5.00 USDDeprecated: Optional parameter $currency declared before required parameter $amount is implicitly treated as a required parameter in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2
5.00 USDDeprecated: format_price(): Optional parameter $currency declared before required parameter $amount is implicitly treated as a required parameter in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2
5.00 USDThe same code on PHP 8.2, 8.3 and 8.5
Deprecated: Optional parameter $currency declared before required parameter $amount is implicitly treated as a required parameter in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2
5.00 USDDeprecated: Optional parameter $currency declared before required parameter $amount is implicitly treated as a required parameter in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2
5.00 USDDeprecated: format_price(): Optional parameter $currency declared before required parameter $amount is implicitly treated as a required parameter in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2
5.00 USD
PHP 7.4 says nothing. PHP 8.0 writes “Required parameter $amount follows optional parameter $currency”. PHP 8.1 turns the sentence around: “Optional parameter $currency declared before required parameter $amount is implicitly treated as a required parameter”. From PHP 8.4 the function’s name comes first. In every case the page is built and the result is the same.
What it means
A parameter with a default value ($currency = 'EUR') is meant to be optional: callers could leave it out. But a required parameter follows it ($amount, without a default), and PHP gives the arguments to the parameters in order, so a call that leaves out $currency can’t give $amount either. The default can never be used. php.net: “If a parameter with a default value is followed by a required parameter, the default value has no effect. This is deprecated as of PHP 8.0.0 and can generally be resolved by dropping the default value, without a change in functionality” (php.net).
That the default never worked is easy to see: leaving out the first argument fails with the same error on PHP 7.4 and on PHP 8.5.
wp-content/plugins/shop-helper/includes/prices.php
<?php
function format_price($currency = 'EUR', $amount) {
return number_format($amount, 2) . ' ' . $currency;
}
echo format_price(5), "\n";
Fatal error: Uncaught ArgumentCountError: Too few arguments to function format_price(), 1 passed in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 6 and exactly 2 expected in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php:2
Stack trace:
#0 /var/www/html/wp-content/plugins/shop-helper/includes/prices.php(6): format_price(5)
#1 {main}
thrown in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2Deprecated: format_price(): Optional parameter $currency declared before required parameter $amount is implicitly treated as a required parameter in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2
Fatal error: Uncaught ArgumentCountError: Too few arguments to function format_price(), 1 passed in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 6 and exactly 2 expected in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php:2
Stack trace:
#0 /var/www/html/wp-content/plugins/shop-helper/includes/prices.php(6): format_price(5)
#1 {main}
thrown in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2Is it urgent?
No. The notice changes nothing in how the site works. It’s worth fixing in the plugin’s next update, since deprecated code is expected to stop working in a future PHP version.
The fix
Delete the default. It changes nothing, because it could never be used:
wp-content/plugins/shop-helper/includes/prices.php
<?php
function format_price($currency, $amount) {
return number_format($amount, 2) . ' ' . $currency;
}
echo format_price('USD', 5), "\n";
5.00 USD5.00 USDSwapping the parameters would also silence the notice, but it changes the order every call must use. That is only safe if the developer changes every call too.
If you run the site, the fix belongs in the plugin: update it (Dashboard → Updates), or send the full message to its developer. Don’t edit the plugin’s files yourself; your changes are lost with its next update.
Finding it before you upgrade
A check that reads code finds this in the function’s declaration, before you switch:
CompatNav reports the usual case. It doesn’t report one variant: a parameter typed with ?, defaulting to null, before a required one. PHP 8.1 and later show the notice for it too, but PHP’s own lists of changes don’t mention that case, and it only checks what they document:
wp-content/plugins/shop-helper/includes/prices.phpCode: the ?Type $x = null variant
<?php
function format_price(?string $currency = null, $amount) {
return number_format($amount, 2) . ' ' . ($currency ?? 'EUR');
}
echo format_price(null, 5), "\n";
5.00 EURDeprecated: Optional parameter $currency declared before required parameter $amount is implicitly treated as a required parameter in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2
5.00 EURDeprecated: format_price(): Optional parameter $currency declared before required parameter $amount is implicitly treated as a required parameter in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2
5.00 EUR
One more case is documented as allowed: “One exception to this rule are parameters of the form Type $param = null, where the null default makes the type implicitly nullable.” (php.net) PHP 8.4 deprecated those implicitly nullable parameters separately; WordPress and PHP 8.4 shows that notice and its fix. How to keep notices off your pages while you wait for updates: Deprecation notice vs fatal error.
Key takeaways
- Two wordings for the same notice: PHP 8.0 says “Required parameter … follows optional parameter …”, PHP 8.1 and later “Optional parameter … declared before required parameter …”. From PHP 8.4 the function’s name comes first.
- The code behaves exactly as before: the default value could never be used, not even on PHP 7.4.
- The fix is to delete the unused default. Moving the parameters around would change every call to the function.
- A check that reads code finds the usual case before you upgrade; one variant with
?Type $x = nullisn’t reported. - The fix belongs in the plugin’s code: update the plugin, or send the message to its developer.
Frequently asked questions
Can I ignore it?
Yes, for now: nothing changes in how the site works. It’s still worth passing on to the plugin’s developer, because deprecated code is expected to stop working in a future PHP version.
Why does the message change between PHP versions?
PHP 8.1 rewrote it to say what PHP actually does: it treats the “optional” parameter as required. PHP 8.4 added the function’s name at the start. The cause and the fix are the same.
Should the parameters swap places instead?
Only the plugin’s developer can decide that: swapping the order changes every call to the function, in the plugin and anywhere else. Deleting the default changes nothing, which is why php.net suggests it.
Check your own site before you upgrade
CompatNav is a free WordPress plugin. It reads the code of your plugins and themes on your own server and tells you, in plain words, what will break and what will only show notices on the PHP version you choose. It never changes your code. It can’t see problems that only appear while code runs with real data, so a quick check of your site after the upgrade still matters.
Sources
- php.net: Deprecated features in PHP 8.0
- php.net: Deprecated features in PHP 8.4.x (implicitly nullable parameters)
About the code examples: each output is the real output of the code shown, run with the official PHP builds, without a php.ini, with all errors reported and displayed. Only the file path was replaced by a neutral server path.