2014年11月2日日曜日

PHPデータ設計の基礎中の基礎「なし」の扱い方

PHPで空や偽など、データ無しの扱い方

PHPはWebアプリ用言語なので、フォームから値を受け取ったり、MySQLからデータを受け取ったりなどを前提とした言語となっています。
そこで、データが空だという事を簡単に判別するための関数が用意されています。

empty(); です。

これで入力データを判別できるようにデータ設計をするのが、拡張性が高くて不具合が発生しにくい設計になるでしょう。

"" (空文字列)
0 (整数 の 0)
0.0 (浮動小数点数の 0)
"0" (文字列 の 0)
NULL
FALSE
array() (空の配列)
$var; (変数が宣言されているが、値が設定されていない)

上記は全て『同じ』として扱います。

悪い設計例としては
1:なし
2:あり

正しい設計は
0:なし
1:あり

もし「なし」が無く全て有効な値だった場合は、1から開始してください。
0はデータ無しで統一すると、将来的に助かる場面がきっと出てきます。

プルダウンリストから選択する場合のインデックスは
0:不正 or 未選択
になります。
選択肢に0が無いのに0が来れば不正として処理。
選択肢に0があって0がくれば未選択となります。
有効なデータは必ず1番目以降を指定してください。


■未定義と空を区別したいケース

空の場合は空で上書きし、未定義の場合は変更無しというケースがあります。
その場合は、 isset(); を使ってください。
未定義とnullのみ同じとなります。

さらに未定義とnullを分けるような設計は複雑化しすぎなので、見直したほうが良いかもしれません。
is_null()を使うことで、nullかどうかの判別は可能です。

■MySQLの場合

nullは可能な限り使わないでください。 nullは特殊なオブジェクトなため、SQL文が面倒なことになります。
たとえば、 'foo' = null とは書けません。 'foo' IS NULL という特殊構文となってしまいます。
これは、nullを使うことで多くの制限が発生することを意味します。
デフォルト値はnullではなく0や空文字を使うようにしましょう。

初心者がPHPではまる3大ケース

PHP初心者がやりがちな間違ったコーディング方法を紹介します。

■文字列の比較

型を自動変換してくれる全ての言語で言える事ですが、文字列を比較する場合は「===」を使わなければなりません。
言語により微妙にこの部分の動作は異なります。

文字列を扱える言語で型が無い言語なんてのはありえません。
自動変換が行われる場合、どう変換されるのかを頭に入れておかないと意図しない結果を招きます。
PHPの比較構文による自動変換では、文字列の1文字目が数字になっていれば数値型に変換されます。
比較のどちらかが数字ならば、全て数値型で統一されます。このとき数字から開始していない文字列は「0」に変換されます。
すなわち、何も考えずに 「===」を使いなさいということになります。

基本的に「===」は変換処理が無いため高速処理されます。「==」を使わなければならない理由が無い限り「===」を使ったほうが良いでしょう。

特に注意したいのは swich文も自動変換が行われるという点です。
swich文のcaseには数値型と文字列型を混ぜないように注意しましょう。

■ && と and

&& と and は同じと勘違いして説明している人が非常に多いです。
両者は動作が異なりますので、結果も異なる事が多いです。
違いは、処理の優先度です。

$g = true && false;
$h = true and false;

上の2つは、結果が異なります。 if文でよく使われる構成ですよね。
ちょっと式が複雑化しただけで、異なる結果になってしまうのです。

「()」をつけて書き直すとこうなります。

$g = (true && false);
($h = true) and false;

上のような動作となります。 処理の優先度が異なります。

and や or は使う必要性が無いため、ソース上に見かけたら理解していない人が書いたと思って間違いありません。
普通は混乱を避けるため、使いやすさのため、 && || で統一されます。

■ソースファイルの最後に「?>」

ソースファイルがPHPで終わる場合、?>を書いてはいけません。
?>はphpの終わりではなく、htmlの開始タグと覚えましょう。
phpの処理では、htmlの出力がされる前でしか実行不可能な処理もあります。
?>の後に空白改行等が意図せず入り込み、PHPがエラーとなるケースがよくあります。