Quantcast
Channel: mattintosh note
Viewing all articles
Browse latest Browse all 891

PHPのnull判定について調べてみる

$
0
0

わけあって書きたくなかった PHP関連の作業をすることになりました。なんてこった。

いままで PHPを書いて生きてこなかったんですが、まぁ Go とか Pythonとか他の言語の知識である程度はなんとかなるものです。

とは言っても PHP学習歴数時間の人間の話です。

とりあえず既存プログラムの改修をしているのですが、う〜ん、どうもこれ PHPというかプログラミングを知らない人間が書いている気がする…と思ったので言語独自の解釈の確認から。(まぁ私もプログラマではないのですが)

で、まぁよくある null の確認です。

f:id:mattintosh4:20191228013415p:plain
https://www.php.net/manual/ja/types.comparisons.php

あぁ、これ見るだけで嫌になりますね。ポイントになるのは上の 4 項目でしょうか。

  • 空文字
  • null
  • 未代入
  • 未定義

似ているようで異なるこれらのパターンですが、この表を見る限り is_null()isset()は真逆の解釈をするようです。つまり is_null() == !isset()または !is_null() == isset()という話です。

PHPだしそんなことないよな〜」と思っていたら案の定違いがありました。

<?phpvar_dump($foo);
var_dump(is_null($foo));
var_dump(!isset($foo));
PHP Notice:  Undefined variable: foo in /tmp/sh-thd-6879852719 (deleted) on line 2
NULL
PHP Notice:  Undefined variable: foo in /tmp/sh-thd-6879852719 (deleted) on line 3
bool(true)
bool(true)

判定は is_null()isset()も同じく trueですが、isset()は変数が Undefined であっても E_NOTICEを吐かないようです。

公式の説明では下記のように書いてあります。(誤字なんとかしろよ)

注意:

$xが定義されていない状態で単に if ($x)としてしまうとE_NOTICE レベルのエラーが発行てしまいます。代わりに、empty()や isset()を使うかあるいは変数を初期化するように してください。

この説明に is_null()が含まれていないところを見ると is_null()E_NOTICEを吐くのでしょう。

E_ERRORではないのだからいいのではないかと済ます人もいるでしょうが私はそういうのが嫌いです。きちんと対処すれば出力されないメッセージのおかげで大事なメッセージが埋もれてしまいます。インフラ的観点からしてもログファイルが肥大化するので勘弁して欲しいです。

で、上の表からするに PHPでは「変数が定義済みかどうかわからない状態で厳密に $foo = nullを正確に調べる方法は is_null()isset()単体では調べられないのでは?」と思った。

PHPの公式には null について下記のように書いてある。null の範囲が広すぎない?

  • 定数 NULLが代入されている場合。
  • まだ値が何も代入されていない場合。
  • unset()されている場合。

上の説明を読むに空文字は「値」に含まれないようだ。シェルで言うところの test -n "${foo}"レベルの判定しかしないっぽい。

SQLでは厳密に null を判定する方法として is nullがあったりするけど、DB と組み合わせて使う PHPの null の解釈がこれではユーザが混乱するのではないだろうか。

コーディングルールも nulltruefalseは小文字で書けと言いつつ、定数だから大文字書くべきなのでは?と思ったり。

厳密に null かどうかを判別するのは同ページの === による厳密な比較に書いてあるがこれだけなようだ。

$foo === null

is_null()isset()などは複数のパターンで判定するのに使えるが厳密なチェックには使えない、と。

やっぱりヤダ PHP


Viewing all articles
Browse latest Browse all 891

Trending Articles