PHP8でのNon-Nullable型へのnull代入におけるTypeError対応ガイド

本記事では、PHP8におけるnon-nullableな引数型へのnull代入時に発生するTypeErrorについて、その概要、原因、具体例、そして対策方法までをわかりやすく解説します。
PHP7からPHP8へ移行する際や、既存コードをメンテナンスする際に役立つポイントをまとめました。

目次

PHP8の型システムとnon-nullable型とは

PHP8では型システムがより厳密かつ明確になりました。
特に、引数に対する型宣言については、nullableかどうかがコード上でよりはっきり示されるようになっています。
たとえば、stringintなどといった基本型を引数として要求するとき、これらは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) { ... }のような関数定義があったとします。
ここで$namestring型であることが前提のため、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とすることで、その引数はstringnullを受け入れるようになります。

<?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を許す・許さないを明示的にコントロールすることが肝要です。
こうした取り組みによって、より明確なコードと信頼性の高いアプリケーションを実現できるでしょう。

関連記事

あわせて読みたい
PHP7からPHP8への移行でよく発生する警告・エラー10選とその対応方法 本記事では、PHP7からPHP8への移行を行う際によく遭遇する警告やエラーを10項目ピックアップし、PHP7とPHP8での差異を踏まえて詳しく解説します。それぞれのケースにつ...
よかったらシェアしてね!
  • URLをコピーしました!
目次