“Optional parameter … declared before required parameter” in WordPress: what it means

By CompatNav · Published · Last reviewed · 5 min read

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";

Output on PHP 7.4.33

5.00 USD

Output on PHP 8.0.30

Deprecated: Required parameter $amount follows optional parameter $currency in /var/www/html/wp-content/plugins/shop-helper/includes/prices.php on line 2
5.00 USD

Output on PHP 8.1.34

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 USD

Output on PHP 8.4.26

Deprecated: 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

The same code on PHP 8.2, 8.3 and 8.5

Output on PHP 8.2.34

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 USD

Output on PHP 8.3.35

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 USD

Output on PHP 8.5.11

Deprecated: 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";

Output on PHP 7.4.33the script stopped

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 2

Output on PHP 8.5.11the script stopped

Deprecated: 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 2

Is 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";

Output on PHP 7.4.33

5.00 USD

Output on PHP 8.5.11

5.00 USD

Swapping 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:

Code: the ?Type $x = null variant

wp-content/plugins/shop-helper/includes/prices.php

<?php
function format_price(?string $currency = null, $amount) {
    return number_format($amount, 2) . ' ' . ($currency ?? 'EUR');
}

echo format_price(null, 5), "\n";

Output on PHP 8.0.30

5.00 EUR

Output on PHP 8.1.34

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 EUR

Output on PHP 8.5.11

Deprecated: 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 = null isn’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.

Get CompatNav on wordpress.org How it works

Sources

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.