PHPで配列の要素数を取得する時、count関数を使うのが一般的ですが、引数にnullを渡すとどうなるかご存知でしょうか。環境やPHPのバージョンによって挙動が変わるため、予期せぬ警告やエラーが発生することがあります。本記事ではPHPのcount関数にnullを渡した場合の仕様、警告・エラーの違い、null判定のベストプラクティスなどを丁寧に解説し、実際の現場で安心して使える方法をまとめています。
PHP count 関数 null による挙動と仕様の基礎
PHPのcount関数は、配列またはCountableインターフェースを実装したオブジェクトの要素数を返す機能がありますが、引数がnullの場合や配列でない値が渡された場合には挙動が異なります。最新の仕様では、nullが渡された時には0を返し、警告やエラーの発生タイミングもバージョンによって変わっています。ここではnullを渡した際の返り値や仕様変更履歴、PHPのバージョン間の違いを詳しく見ていきます。
count(null) の返り値:どのようになるか
nullを引数に指定した場合、count関数は要素が0個の配列と同じようにゼロを返します。ただし、配列でない他のスカラー型(例えばfalseなど)が渡された場合は、以前のバージョンでは1を返したり警告を出したりしていたため、混乱の原因となることがあります。返り値と発生する通知・警告の違いを理解することが重要です。最新情報では、nullである引数には0を返す仕様になっています。
警告やエラー:バージョンごとの違い
PHP 7.2以降では、count関数にnullを渡すと「警告(warning)」が発生する場合があります。具体的には、引数がcountableでない型であるための警告が追加され、文書にもその旨の記述が更新されました。PHP 8.0以降では、count関数に配列またはCountable以外の型を渡すとTypeErrorがスローされるケースがあり、nullもこの対象となります。バージョンによっては警告で済むか致命的なエラーになるかが変わるため、使うPHPのバージョンを確認することが必要です。
仕様変更の歴史:なぜこのようになったか
過去には、count関数にスカラー型やオブジェクト(Countableを実装しないもの)を渡した時、null以外の値では1を返すという挙動がありました。この挙動が分かりにくいという声が多数あり、counting_non_countablesというRFCで議論がなされ、警告を出すよう仕様が変わりました。PHP 7.2で警告追加、PHP 8.0でCountableでない型に対してTypeErrorを投げる仕様になりました。nullの場合は返り値0という例外的扱いが継続しています。
nullが関わる典型的なエラーや問題シナリオ
開発現場でcount(null)が原因となるトラブルは意外と多く起こります。引数が意図しないタイミングでnullであったり、データの取得先でnullが想定外に混じっていたりすることがあります。これらを予防するためには、警告・エラーの内容を把握し、null判定や型チェックを適切に挟むことが重要です。ここではよくある問題シナリオとその原因、そして実践的な防止策を紹介します。
警告やTypeErrorが発生するパターン
PHP 7.2以降、count関数に対してnullや空文字列、Countableを実装しないオブジェクトが渡されると警告が発生します。PHP 8.0以降は、配列やCountableを実装していない型にnullを含め、危険な引数を渡すとTypeErrorが発生することがあります。これによりアプリケーションが中断することもあるため、事前チェックやバージョンに応じた対応が求められます。
配列要素がすべてnullの場合の誤検出
配列に複数の要素があって、その全てがnullである場合、count関数だけでは要素数を「0ではない」と判断してしまいます。利用者から見ると「中身がない」と思っていたのに、countで数えてみると非ゼロになるため、想定外の挙動となるケースがあります。こうした状況ではarray_filterやループでnull以外の値をチェックする必要があります。
Null値の混入によるデータ処理のバグ
外部APIやデータベースから取得した値がnullであり、それを配列として操作するコードでnullチェックがない場合、foreachや配列関数でエラーになることがあります。また、JSONデコード後の値がnullかどうかで処理を決める必要があるケースも多く、nullが存在するかどうかでロジックが変わることがあります。
nullを安全に扱うためのコード実践とベストプラクティス
nullを含む値をcount関数で扱う際、予防的にチェックを入れることで警告やエラーを防ぎ、コードの可読性と堅牢性を高めることができます。ここでは具体的にどのようなチェックを入れるか、関数化すべき部分、配列だけでなくオブジェクトにも対応する方法など、現場で即実戦できる方法を多数紹介します。
isset・is_null・is_countableを使った前処理
まずcountを呼び出す前に、変数が存在しているかどうかをissetで確認し、nullかどうかはis_nullでチェックします。PHP 7.3以降にはis_countable関数があり、引数が配列かCountableかを確認できます。これらを組み合わせて、countを安全に呼び出すガード条件を作ることで警告やエラーを未然に防げます。
array_filterでnullを除去してからcountする方法
配列の中にnull値が混ざっているかどうかが問題となる場合、array_filterを使ってnull値を取り除いてからcountを取るのが有効です。array_filterにコールバックを渡してnull以外を残す方法があり、純粋に「中身のある要素数」を取得できます。大きな配列やパフォーマンスが重要な場面では注意して使いたいテクニックです。
デフォルト値の設定とnull合体演算子
引数がnullかもしれない場合、null合体演算子を使ってデフォルト値を設定することで処理を簡略にできます。たとえば変数を配列として初期化するか、nullなら空配列に置き換えてからcountを実行する方法です。この方法ならnullによるエラーや警告を回避できます。
PHP バージョン別の対応:最新のPHPにおける注意点
PHPのバージョンによりcount関数の仕様が異なるため、運用しているバージョンに応じた対応が重要です。最新の環境ではCountableでない型に対してTypeErrorが投げられる可能性があるため、従来の癖でnullやスカラーを引数にするコードは見直しが必要です。ここではPHP 7系と8系、さらにはその後のマイナーアップデートで注意すべき点を整理します。
PHP 7.2~7.4での警告挙動
PHP 7.2以降、count関数にnullや空文字列、Countableを実装しない型を渡すと警告を出すようになっています。nullの場合は返り値0ですが、警告が発生するのでエラーログに記録される可能性があります。開発環境・本番環境ともに警告を非表示にする設定ではなく、コード側で対策することが推奨されます。
PHP 8.0以降でのTypeError発生の可能性
PHP 8.0で型システムが強化され、count関数にCountableまたは配列でない型を渡すとTypeErrorをスローする仕様が導入されたため、nullを引数にするコードは例外処理や事前チェックがないと重大なエラーとなります。互換性を保つためには、nullチェックあるいはis_countableの利用が必須です。
将来のバージョンに向けた互換性を保つ方法
PHPの将来バージョンでもCountableでない型の扱いはより厳格になる可能性があります。そのため、関数やメソッドの引数からなるデータは可能な限り型宣言を使い、nullを許すかどうかを明示する設計が望まれます。さらに、ライブラリやフレームワークで共有されるAPIではnull可能な型と非null型を明確にし、テストでnullが渡された場合の挙動を検証することが重要です。
サンプルコードで理解する実践例
具体的なコード例を見てみると、null判定を入れた守りのコードと、array_filterを使ったnull除外などの実践的な方法が理解しやすくなります。ここではいくつかの代表例を紹介し、それぞれの利点と書き方を比較します。サンプルはPHPの最新仕様を想定して書かれており、実際の開発現場で応用できる形式です。
基本的なnullチェック付きcountの例
if(isset($items) && is_countable($items)) {
$cnt = count($items);
} else {
$cnt = 0;
}
このコードは、変数が存在するか、かつ配列またはCountableかを確認した上でcountを呼び出します。issetで存在チェック、is_countableで正しい型を確認するため、nullや他の型が混じっていても安全です。デフォルト値を0とすることで処理が継続可能になります。
null値を除外して要素数を取得する例
$filtered = array_filter($array, function($v) {
return $v !== null;
});
$countNonNull = count($filtered);
配列の中にnullが含まれていることが問題となるシナリオに対しては、この方法が直接的です。array_filterとコールバックを使ってnullだけを除去し、新しい配列の要素数を数えます。元の配列を変更したくない場合でもこの方法は有効ですし、読みやすさも保てます。
関数化して再利用可能なユーティリティ作成例
function safe_count($value): int {
if(is_countable($value)) {
return count($value);
}
return 0;
}
このような関数を作っておけば、コード中のcount呼び出しをすべて置き換えることで一斉に安全性を高められます。引数にnullや他の不正な型が渡されても0を返すように設計されており、例外処理を入れる必要も最小限になります。
比較:関数・空チェック・null処理方法のメリット・デメリット
nullを扱う方法には複数選択肢がありますが、それぞれ特徴があります。ここでは主な方法を比較し、どの場合にどの手法を使うべきかを整理します。パフォーマンス、安全性、可読性などの観点で比較することで、自分のプロジェクトに合った方法を選びやすくなります。
| 手法 | メリット | デメリット |
|---|---|---|
| isset+is_countableによるチェック | 不正な引数を避けられ、警告・エラーを防げる。実行速度も速い。 | コード量が増える。繰り返しチェックを書くと冗長に見える。 |
| array_filterでnull除去後count | 実際にnull以外の要素だけを数えたい時に正確。読みやすい。 | 大量配列でフィルター処理がオーバーヘッドになる可能性。メモリ使用増。 |
| 関数safe_countなどのユーティリティ | 一元管理でコードの見通しが良い。保守性が高い。 | ユーティリティがブラックボックスになりがちで、内部の挙動を理解していないと誤用する恐れ。 |
まとめ
count関数にnullを渡すと、最新のPHP環境では返り値が0となり、警告やTypeErrorが発生する可能性があります。環境に応じたバージョン確認がまず重要です。
nullを安全に扱うには、isset、is_null、is_countableでチェックを入れ、array_filterで不要なnullを除去するか、safe_countのような関数を使ってコードしっかり設計することが有効です。
配列内に要素があってもすべてnullなら、count関数だけでは「中身なし」と判定できないので、そのようなケースには特別なチェックが必要です。
PHPの今後のバージョンでも型安全性は高まる見込みがあり、nullを含めた値を引数に取る関数は入力の型を明らかにする設計が求められています。開発現場ではこのような仕様を意識してコードを作ることで、エラーを防ぎつつ信頼性を高められます。
コメント