PHP empty()とisset()の違い

4617 ワード

に縁を付ける
今日APIインタフェースを書いて、empty()によって引き起こされた穴に出会った.
背景
機能要求:GETに従って、データテーブルフィールドを更新する;このパラメータの値範囲:0, 1, 2;考え方:$_GET['var']でパラメータ値を取得し、SQL文をつづる.
1回目の試み$_GET['var']を使用してパラメータ値を取得する場合、if(!empty($status))を使用してパラメータ値が存在するかどうかを判断し、SQL文を接続するかどうかを決定することは自然に考えられます.
$sql_condition = ' AND id = :id';

$status = $_GET['status'];
if(!empty($status)){
    $sql_condition .= ' AND status = :status';
}
テストの結果、status == 0の場合、!empty($status)falseであり、SQL文のつづりを直接省略することが分かった.
マニュアルを見ると、empty()の機能は「空かfalseと思われるか」を判断することである.
Determine whether a variable is considered to be empty. A variable is considered empty if it does not exist or if its value equals FALSE
PHPでは、以下の状況はfalseとされています.
  • the boolean FALSE itself
  • the integer 0 (zero)
  • the float 0.0 (zero)
  • the empty string,and the string“0”(空の文字列と値が0の文字列!)
  • an array with zero elements(空の配列)
  • an object with zero member variables (PHP 4 only)
  • the special type NULL(including unset variables/破棄された変数を含む)
  • SimpleXML objects created from empty tags

  • すなわち、$status == 0の場合、empty($status)は実際にコンピュータによってempty(false)と理解され、結果としてtrueであるため、逆の場合、!empty(false)falseであるempty()が数字0を効率的に処理することができない以上、isset()の関数を用いて判断することが考えられる--そこで次の2回目の試みが行われた.
    2回目の試み
    $sql_condition = ' AND id = :id';
    
    $status = $_GET['status'];
    if(isset($status)){
        $sql_condition .= ' AND status = :status';
    }
    
    テストではstatus == 0が解決したことがわかりましたが、status == ''(つまりstatusが空の配列)ではisset($status)trueとなり、SQL文のつなぎ合わせになり、データベースのエラー書き込みが発生しました!
    マニュアルを見ると、$varが空の配列である場合、isset($var)が真であることがわかる.
    この时、考えが少しぼんやりしているような気がします.
    インターネットで検索すると、empty()isset()の違いを直感的に観察できる比較表がまとめられていることがわかりました.
    を選択します.
    gettype()
    empty()
    is_null()
    isset()
    (bool)
    $x = "";
    ストリングス
    true
    false
    true
    false
    $x = null;
    NULL
    true
    true
    false
    false
    var $x; (not set)
    NULL
    true
    true
    false
    false
    $x = array();
    array
    true
    false
    true
    false
    $x = false;
    bollan
    true
    false
    true
    false
    $x = 15;
    integer
    false
    false
    true
    true
    $x = 1;
    integer
    false
    false
    true
    true
    $x = 0;
    integer
    true
    false
    true
    false
    $x = -1;
    integer
    false
    false
    true
    true
    $x = "15";
    ストリングス
    false
    false
    true
    true
    $x = "1";
    ストリングス
    false
    false
    true
    true
    $x = "0";
    ストリングス
    true
    false
    true
    false
    $x = "-1";
    ストリングス
    false
    false
    true
    true
    $x = "foo";
    ストリングス
    false
    false
    true
    true
    $x = "true";
    ストリングス
    false
    false
    true
    true
    $x = "false";
    ストリングス
    false
    false
    true
    true
    これらの概念を明確に区別した後、考え方を再整理します.
  • 私が達成したい効果は:
  • パラメータ値が空の場合、論理的にfalseと判断し、SQL文のパッチをスキップすることができる.
  • パラメータ値が0の場合、論理的に真と判断し、SQL文のつづりを行う.
  • 上記の表によると、empty()は明らかに私の2つの特殊な要求を満たすことができず、isset()は「パラメータ値が0」の場合しか満たすことができない.
  • 直接的な関数が見つからず、「または非」の論理条件を用いて判断条件を豊富にしようと試みる.最終的に選択された判断条件はif(isset($status) && $status != '')であり、以下の3回目の試みを参照する.
    3回目の試み
    $sql_condition = ' AND id = :id';
    
    $status = $_GET['status'];
    if(isset($status) && $status != ''){
        $sql_condition .= ' AND status = :status';
    }
    
    テストの后、需要を満たすことを确认します.ただ、コードが少し丑くて、この解决方法に対して少し底気がありません(囧)、StackOverflowを探して、似たような答えがあります:
    if ( isset($_GET['gender']) and ($_GET['gender'] != '') )
    {
      ...
    }
    
    自分の解決策が合理的だと確信していますBingo!^_^その他のソリューション
    私の場合、is_int()は直接要求を満たしました.
    $sql_condition = ' AND id = :id';
    
    $status = $_GET['status'];
    if(is_int($status){
        $sql_condition .= ' AND status = :status';
    }
    
    文章の歴史.
  • 2016/12/20(初回リリース)
  • 2018/01/31(is_int()添加ソリューション;着色)
  • もし私の文章があなたに役に立つと思ったら、「好き」を打って、あるいは改善のアドバイスをしてください.