PHPは、定期的にバージョンアップします。
その都度仕様変更部分があるのですが、今回過去に作ったプログラムが、「文法エラー」となり動作しないことがありました。
そういえば、以前PHP7.4になったときにも似たようなことがありました。
結果的にはちょっとしたことでしたが、最初は意味が分からず四苦八苦しました。
忘備録として記録いたします。
現象は次の通りです。
Deprecated: Required parameter $p3 follows optional parameter $p2 in
というエラーがでる。
PHPバージョンアップでエラーが出るようになると、いつも思います。
「いったい何がいけないのか?」
今までエラーではなかった記述がエラーとなるのですから、頭を抱えます。
原因:関数の初期値設定不備によるエラー
今回のエラーは、次の記述で発生します。
<?php
test(1, 2, 3);
function test($p1, $p2=null, $p3)
{
return;
}
?>
一見何の問題もなさそうですが、関数test()の引数に原因があります。
引数$p2は初期値NULLが指定されています。
しかし、$p3には初期値が指定されていません。
これがエラーの原因です。
一度初期値を指定したら、以降の引数にも初期値を指定しないとPHP8ではエラーになります。
対処方法:初期値を設定した以降の引数にも初期値を指定する
次のように記述すれば、エラーがなくなります。
<?php
test(1, 2, 3);
function test($p1, $p2=null, $p3=null)
{
return;
}
?>
関数test()の$p3にも初期値を設定すると、エラーが直ります。
一度初期値を設定したら、以降の引数にも初期値を設定しないと、文法エラーとなるのです。
注意点:引数の初期値は必須ではありません。
一見、関数の引数初期値が必須になったように見えますが、そうではありません。
ややこしいことに、次の記述のように、引数の初期値が全くないとエラーにはなりません。
<?php
test(1, 2, 3);
function test($p1, $p2, $p3)
{
return;
}
?>
- 初期値がないなら、それでOK。
- 初期値を設定するなら、後ろの引数すべてに初期値が必要。
今まで意識していませんでしたが、関数の引数に初期値を設定するということは、呼び出し側で省略が可能ということです。
第2引数が省略可能なのに、第3引数が必須というのも確かにおかしな話です。
この場合引数の順番を入れ替える対処方法もありかもしれません。
ただ、呼び出している箇所が多い場合は、素直に初期値を入れるほうがよさそうです。