中級のPHPエラー 36問
12種類のエラーを、それぞれ複数パターンずつ収録しています。
- foreachで&を使った後、unsetを忘れると値が壊れるforeach ($arr as &$v) で配列を参照渡しで回すと、ループ終了後も$vは配列の最後の要素への参照を保持し続けます。unset($v)を忘れると、次に$vという名前でループを回したときに最後の要素が上書きされます。
- 配列を別の変数に代入するとコピーされる(参照ではない)PHPの配列はオブジェクトと違い、代入すると中身がまるごとコピーされます。コピー先の配列を変更しても、元の配列には影響しません。
- staticプロパティを self:: なしで参照すると別の変数として扱われるクラス内からstaticプロパティにアクセスするには self::$prop のように書く必要があります。$propとだけ書くと、staticプロパティとは無関係のローカル変数として扱われ、Warningが出ます。
- Cannot access private property の原因と直し方privateで宣言したプロパティにクラスの外からアクセスしようとすると、致命的エラーになります。外部に公開したい値はpublicにするか、getterメソッド経由で提供する必要があります。
- Cannot instantiate abstract class の原因と直し方abstractを付けたクラスは、そのままnewしてインスタンス化することができません。abstractクラスはサブクラスに実装させるための設計図であり、必ず継承先のクラスを使う必要があります。
- インターフェースのメソッドを実装し忘れると Fatal error になるimplementsで宣言したインターフェースのメソッドを1つでも実装し忘れると、そのクラス自体を読み込んだ時点で致命的エラーになります。インスタンス化する前、クラスの定義そのものが不完全と判定されます。
- declare(strict_types=1) で型の異なる引数を渡すと TypeError になるファイルの先頭でdeclare(strict_types=1)を宣言すると、関数の型宣言と異なる型の値を渡した際に自動変換されず、TypeErrorになります。strict_typesが無い場合は自動的に型変換されて実行が続きます。
- ArgumentCountError: Too few arguments passed の原因と直し方関数が必要とする数より少ない引数しか渡さなかったときに出るエラーです。デフォルト値の無い引数を省略すると、PHP8では実行時エラーとして止まります。
- match式で該当する条件が無いと UnhandledMatchError になるmatch式は該当するcaseが1つも無いと、switch文のように黙って何もしないのではなく、UnhandledMatchErrorという例外を投げます。想定していない値が来た場合の安全装置として働きます。
- ?? を使わずに存在しないキーへアクセスするとWarningが混ざる配列のキーが存在するか分からない場合、??演算子を使えばWarningを出さずにデフォルト値を指定できます。??を使わずにそのままアクセスすると、Undefined array keyのWarningが出力に混ざります。
- strpos()が0を返すと if文でfalseと同じに扱われてしまうstrpos()は文字列が先頭(添字0)で見つかった場合、戻り値の0を返します。if ($pos)のように真偽値として直接判定すると、0はfalseとして扱われるため、先頭で見つかったのに「見つからなかった」と誤判定します。
- array_merge()は文字列キーが同じだと上書きし、数値キーは振り直すarray_merge()は文字列キーが重複していると後の配列の値で上書きし、数値キーは重複を無視して0から振り直します。片方の配列のデータが消えたように見えるのは、この仕様が原因です。