はじめに
こんにちは、普段は業務で求人系サービスの開発や社内向けツールの開発を行なっている@taku-0728です。
今回はPHPの存在チェックによく使われるisset
と、その逆として取り上げられるis_null
の違いについて取り上げます。公式ドキュメントの型の比較表などではisset
とis_null
の結果は正反対で記載されているのでisset = !is_null
だと思う方もいるかもしれませんが、実はこの2つには違いがあります。
知っている人からしたら当たり前かもしれませんが、比較表だけみたら同じように思えるので、詳細を調べたことがない方は参考にしてもらえればと思います。
結論
細かいことはいいから先に結論が知りたい人向けに結論をまとめます。
isset
と!is_null
で違いがあるのは下記です。
- 未定義の変数を比較した場合
- 実行速度
以下で順番に解説していきます。
解説
未定義の変数を比較した場合
<?php
$x = 'test';
var_dump(isset($y));
?>
上記のコードの実行結果は下記のようになります。
bool(false)
それに対し、下記のコードはどうなるでしょうか
<?php
$x = 'test';
var_dump(!is_null($y));
?>
答えはこうなります。
PHP Notice: Undefined variable: y in test2.php on line 5
issetでは未定義の変数を比較してもエラーになりませんが、!is_nullだとエラーになります。
なぜこのようになるか解説していきます。
isset
isset — 変数が宣言されていること、そして NULL とは異なることを検査する
公式ドキュメントより
isset
は変数が宣言されていることと、NULLではないことを検査するので、実行結果はfalseになります。
is_null
is_null — 変数が NULL かどうか調べる
公式ドキュメントより
is_null
は変数がNULLかどうかを調べるのみであり、isset
とは違って変数が宣言されてるかどうかは検査してくれません。そのため結果はissetとは異なります。
公式ドキュメントの解説を読んでいただければもう解説する必要はないと思いますが、isset
は変数が宣言されていることを確認してくれますが、is_null
はNULLかどうかしか確認してくれません。そのため未定義の変数を比較すると差が生まれるというわけです。
実行速度
isset
と!is_null
の実行速度に違いがあるのか1000万回比較して検証してみます。
<?php
$check_data = "";
// isset
$start_time1 = microtime(true);
$sum = 0;
for ($i=0; $i<=100000000;$i++) {
if (isset($check_data)) {
$sum += $i;
}
}
$end_time1 = microtime(true);
var_dump('isset処理時間:'.($end_time1 - $start_time1)."秒\n");
// is_null
$start_time2 = microtime(true);
$sum = 0;
for ($i=0; $i<=100000000;$i++) {
if (!is_null($check_data)) {
$sum += $i;
}
}
$end_time2 = microtime(true);
var_dump('!is_null処理時間:'.($end_time2 - $start_time2)."秒\n");
?>
3回実行してみましたが、実行結果は過去のようになりました。
string(37) "isset処理時間:1.1999080181122秒
"
string(39) "!is_null処理時間:1.6563079357147秒
"
string(37) "isset処理時間:1.2162489891052秒
"
string(39) "!is_null処理時間:1.6646618843079秒
"
string(37) "isset処理時間:1.1731791496277秒
"
string(38) "!is_null処理時間:1.658478975296秒
"
2つの処理時間には大体0.4~0.5秒ほどの差があることがわかります。
今回は条件式の中でカウンタ変数の加算をしているだけなので大した差にはなっていませんが、
条件式の中が複雑になるほど処理時間に差は生まれると思います。
(追記 コメントにてご指摘をいただきましたが、誤った理解でしたので訂正しておきます)
では同じようなことをやっているのになぜ差が生まれるのでしょうか?
言語構造と関数の違い
isset
と!is_null
の処理速度に違いが生まれる理由はisset
がPHPの言語構造であり、is_null
は関数だからです。
言語構造とはその名の通り、言語を構成する要素のことです。関数のように定義して使うものではなく、すでにPHPの中に組み込まれた機能のことです。
PHPの言語構造一覧についてはこちらの公式ドキュメントを参照ください。
言語構造はPHPの中にすでに組み込まれているので、関数より先に確認にいきます。だから関数であるis_null
よりも、言語構造であるisset
で比較する方が処理速度が早くなるわけです。
また、isset
は言語構造であるが故に未定義の変数から値を取得しようとしてもエラーにはなりませんが、is_null
は関数であるため未定義の変数から値を取得しようとするとエラーになるわけです。
まとめ
PHPのisset
と!is_null
には
- 未定義の変数を比較した場合
- 実行速度
の2つに違いがあります。その理由はisset
がPHPに予め組み込まれた言語構造であるのに対し、is_null
は関数だからです。
基本的に変数の存在チェックにはisset
を使えば問題ないとは思いますがisset
とis_null
は必要と用途に応じて使い分けた方がいいと思いますが、isset
は空文字''
をtrueとしてしまうので値が入っているかどうかを比較する際にはお気をつけください。
また、!is_null
は !== null
と等価ですのでこちらも好みに合わせて使い分けてください。