18
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHPとJSの空チェック一覧

Last updated at Posted at 2014-10-31

PHPのemptyの挙動が不安になったのでまとめてみた。
ついでにJSの空チェックの挙動も調べた。
empty()を使う時は大抵!empty()(存在する)の形で使ってるので、この記事の中では全て!empty()の形で動作チェックをしています。

PHPの場合

空チェックリスト

公式マニュアルが見難いので、全て「存在する」側にまとめてみた。
PHP: PHP 型の比較表 - Manual
http://php.net/manual/ja/types.comparisons.php
動作確認
http://codepad.org/Cgl6apJa

value memo gettype() !empty() (bool) !! isset() !is_null()
true boolean 1 1 1 1 1
false boolean 0 0 0 1 1
1 integer 1 1 1 1 1
0 integer 0 0 0 1 1
1.0 double 1 1 1 1 1
0.0 double 0 0 0 1 1
'1' string 1 1 1 1 1
'0' string 0 0 0 1 1
"1" string 1 1 1 1 1
"0" string 0 0 0 1 1
'1.0' string 1 1 1 1 1
'0.0' string 1 1 1 1 1
"1.0" string 1 1 1 1 1
"0.0" string 1 1 1 1 1
'' string 0 0 0 1 1
"" string 0 0 0 1 1
array() array 0 0 0 1 1
null NULL 0 0 0 0 0
$a 未定義の変数 NULL 0 0 (Noticeが出る) 0 (Noticeが出る) 0 0 (Noticeが出る)
function() {} php 5.3 以降 object 1 1 1 1 1

まとめ

  • シングルクォートとダブルクォートの判定の差はない
  • !empty()(bool)!!の判定はほぼ同じ
    • (bool)!!は同じ
      • というか、PHPのifの中では内部的にbool型に変換して解釈してる
    • (bool)!!は未定義の変数に対して使うとPHP Notice: Undefined variableで怒られる
    • 「文字列の0.0」はtrueになる
      • 文字列の0.0をfalseで判定させる機会は少ないと思われるが、一応気にかけておくこと
  • isset()!is_null()の判定はほぼ同じ
    • !is_null()は未定義の変数に対して使うとPHP Notice: Undefined variableで怒られる
  • phpで空判定をしたい時はempty()isset()を使うのが無難
  • isset()は「変数にnull以外の何かが入っていたらtrue」
  • empty()は「0っぽい時(長さとか)はtrue」
  • isset()empty()は言語構造なのでPHP Noticeが出ない

まとめ追記

array_key_exists()も、配列の空チェックにおいて重要になので追記。
http://codepad.org/IUs7iFdD

以下の構造に対してチェックした結果

$check_list = array(
    'a' => 0,
    'b' => '',
    'c' => null,
//    'd' => null,
);
key !empty() isset() array_key_exists()
'a' false true true
'b' false true true
'c' false false true
'd' false false false

重要なのは中身がnullのkeyのisset()falseになることです。
keyが有る無しのチェックはキチンとarray_key_exists()を使って、中身の有る無しのチェックは!empty()isset()を使いましょう。

Javascriptの場合

空チェックリスト

FireFox 33.0 と Chrome 38.0.2125.104 m で確認。
下の表でtoString.call()と書かれている部分は、Object.prototype.toString.call()で確認した結果。
notEmpty()は自作関数、ページの下の方で解説します。

value typeof toString.call() Boolean() !! notEmpty()
true boolean [object Boolean] true true true
false boolean [object Boolean]
1 number [object Number] true true true
0 number [object Number]
1.0 number [object Number] true true true
0.0 number [object Number]
'1' string [object String] true true true
'0' string [object String] true true
"1" string [object String] true true true
"0" string [object String] true true
'1.0' string [object String] true true true
'0.0' string [object String] true true
"1.0" string [object String] true true true
"0.0" string [object String] true true
'' string [object String]
"" string [object String]
undefined undefined [object Undefined]
null object [object Null]
[] object [object Array] true true
{} object [object Object] true true
function() {} function [object Function] true true true

まとめ

  • シングルクォートとダブルクォートの判定の差はない
  • Boolean()!!の判定は同じ
  • typeofで調べると、null、array、objectが全部objectと判定される
    • Object.prototype.toString.call()で調べると、ちゃんとした型がわかる
  • 真偽値と数値の判定はPHPと同じ
  • 文字列は中に空文字以外が入ってたら全部trueになっちゃう
    • 0文字列を弾きたかったら別途対応する
  • 配列とオブジェクト(連想配列)は全部true
    • 空配列を弾きたかったら、別途対応する

JSでPHPの!emptyっぽい挙動対応版

JSでも0文字列と空配列を弾きたかったので、作ってみた。

not_empty.js
function notEmpty(value) {
    var result;
    switch (typeof value) {
    case 'string':
        // 文字の0を除く
        result = (value && value != 0);
        break;
    case 'object':
        // 配列の中身の数チェック
        result = (value && Object.keys(value).length);
        break;
    default:
        result = value;
    }
    return Boolean(result);
}

三項演算子を使った1行ver。

not_empty_min.js
function notEmpty(v) {
    return Boolean(
        typeof v == 'string' ?
            v && v != 0 :
        typeof v == 'object' ?
            v && Object.keys(v).length :
            v
    );
}
  • 文字列の0対応
    • result = (value && value != 0);
      • value != 0のところで文字列0をfalseにする
      • PHPと違って文字列0.0もfalseにするけど、むしろその方が自然な気がするので気にしないことにする
  • 空配列対応
    • result = (value && Object.keys(value).length);
    • Object.keys(value).lengthのところでオブジェクトのkeyのリストを取得して、その長さを出している
      • 長さが0で無ければok
      • 配列もオブジェクトもObject.keys(value).lengthで項目の数がわかる
    • Object.keys(null)はnon-objectとか言われるので、先に最初のvalueのところでfalse判定して弾いている
18
23
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?