本記事では、PHP8におけるnon-nullableな引数型へのnull代入時に発生するTypeErrorについて、その概要、原因、具体例、そして対策方法までをわかりやすく解説します。
PHP7からPHP8へ移行する際や、既存コードをメンテナンスする際に役立つポイントをまとめました。
PHP8の型システムとnon-nullable型とは
PHP8では型システムがより厳密かつ明確になりました。
特に、引数に対する型宣言については、nullableかどうかがコード上でよりはっきり示されるようになっています。
たとえば、string
やint
などといった基本型を引数として要求するとき、これらはnon-nullable、つまりnullを受け付けない前提であると解釈されます。
この非NULL性は、プログラム全体の整合性や予期せぬ型エラーを防ぐために大きく貢献します。
PHP7からPHP8での変化
PHP7までは、non-nullableとして宣言しているつもりであっても、nullが引数に渡された場合にエラーが発生せず、内部的に無視される、あるいは後続処理で予期せぬ不具合を招くケースがありました。
言い換えれば、PHP7では型宣言やnullable性についてやや曖昧な挙動が見られたわけです。
しかし、PHP8ではこの点が明確に強化され、non-nullableな引数にnullが渡されると即座にTypeErrorが投げられるようになりました。
この変更は一見厳しく思われるかもしれませんが、明示的なエラーによって問題個所を早期発見し、バグの抑止やデータの整合性確保に大いに役立ちます。
Non-nullable型へのnull代入問題の概要
PHP8において、function greet(string $name) { ... }
のような関数定義があったとします。
ここで$name
はstring
型であることが前提のため、nullを渡すことはできません。
もしgreet(null);
のような呼び出しを行うと、PHP8では次のようなTypeErrorが即座に発生します。
TypeError: Argument #1 ($name) must be of type string, null given
このエラーは、開発者に「この関数はstringを必須としているが、nullが来てしまっている」という問題を明確に伝えます。
PHP7以前で「とりあえず通っていた」コードがPHP8下で突然エラーを発するようになった場合、こうした非NULL引数へのnull渡しが原因である可能性が高いです。
エラー例
次に、実際のサンプルコードを確認してみます。
<?php
function greet(string $name) {
echo "Hello, $name!";
}
greet(null); // PHP8でTypeError
PHP8実行環境でこのコードを走らせると、先ほどのTypeErrorが発生します。
これは$name
がstring型であると明示されているため、nullを受け入れられないことが理由です。
Non-nullable型に対する対応策
こうしたエラーを回避するためには、引数がnullになりうる可能性を事前に考慮する必要があります。
対策としては以下の2つが代表的です。
1. Nullable型を明示する
引数がnullになる可能性がある場合、型宣言に?
を付けてnullable型とします。
たとえば?string
とすることで、その引数はstring
かnull
を受け入れるようになります。
<?php
function greet(?string $name) {
if ($name === null) {
echo "Hello, Guest!";
} else {
echo "Hello, $name!";
}
}
greet(null); // これはOK
greet("John"); // "Hello, John!"
このように、nullable型を明示しておくと、nullを受け取った場合の処理を関数内にしっかり記述できます。
2. 呼び出し側でnullにならないようにする
別のアプローチとしては、関数を呼び出す前段階でnullを許さない設計を徹底する方法があります。
たとえば、ユーザー入力や外部APIのレスポンスを受け取る箇所でnull判定を行い、nullが来た場合には別の処理を行う、あるいは適切なデフォルト値をセットすることが考えられます。
// 呼び出し前にチェック
$name = getUserName(); // ここでnullが返る可能性があるとする
if ($name === null) {
$name = "Guest";
}
greet($name); // greet関数は非NULL前提
この戦略によって、greet
関数がnullを受け取ることを防ぎ、確実にstring型を渡すことができます。
Non-nullable引数における設計観点
非NULLを前提とする関数は、関数内部がより単純化され、型に関する不整合を減らします。
ただし、その分外部のコード(呼び出し元)でnullを考慮し、明示的なnullチェックやnullableな設計を行う必要が出てきます。
このような方針は、システム全体の型整合性を高め、将来的な拡張やリファクタリングの際にも有効です。
まとめ
PHP8では、non-nullable型の引数にnullを渡すと直ちにTypeErrorが発生します。
これはPHP7以前には存在しなかった厳格な仕様であり、一見すると不便に思えるかもしれません。
しかし、エラーによって問題が明確化されることで、型不整合や予期せぬバグを早期に発見でき、より堅牢なコードを書くことが可能になります。
対策としては、nullable型を積極的に活用したり、呼び出し側でnullを排除するロジックを用意したりするなど、設計段階でnullを許す・許さないを明示的にコントロールすることが肝要です。
こうした取り組みによって、より明確なコードと信頼性の高いアプリケーションを実現できるでしょう。