web-dev-qa-db-ja.com

PHPの文字列をブール値に解析する

今日、私はPHPで遊んでいて、文字列値「true」と「false」が条件でブール値に正しく解析されないことを発見しました。たとえば、次の関数を考えます。

function isBoolean($value) {
   if ($value) {
      return true;
   } else {
      return false;
   }
}

私が実行した場合:

isBoolean("true") // Returns true
isBoolean("") // Returns false
isBoolean("false") // Returns true, instead of false
isBoolean("asd") // Returns true, instead of false

「1」と「0」の値でのみ動作するようです:

isBoolean("1") // Returns true
isBoolean("0") // Returns false

「true」と「false」の文字列をブール値に解析するネイティブ関数がPHPにありますか?

115
Mark

PHPのfilter_varメソッドを使用するネイティブのPHPメソッドがあります:

$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN);

PHPのマニュアル によると:

「1」、「true」、「on」、および「yes」に対してTRUEを返します。それ以外の場合はFALSEを返します。

FILTER_NULL_ON_FAILUREが設定されている場合、「0」、「false」、「off」、「no」、および「」に対してのみFALSEが返され、ブール値以外のすべての値に対してNULLが返されます。

381
Eric Caron

理由は、"0"および""(空の文字列)を除き、すべての文字列はブールに変換するときにtrueと評価されるためです。

次の関数は、希望どおりに動作します。PHPとまったく同じように動作しますが、文字列"false"falseとして評価します。

function isBoolean($value) {
   if ($value && strtolower($value) !== "false") {
      return true;
   } else {
      return false;
   }
}

ドキュメントはそれを説明しています: http://php.net/manual/en/language.types.boolean.php

ブール値に変換する場合、次の値はFALSEと見なされます。

  • ブール値FALSE自体
  • 整数0(ゼロ)
  • フロート0.0(ゼロ)
  • 空の文字列、および文字列「0」
  • 要素がゼロの配列
  • 特殊タイプNULL(未設定変数を含む)
  • 空のタグから作成されたSimpleXMLオブジェクト

他の値はすべてTRUE(すべてのリソースを含む)と見なされます。

14
Arnaud Le Blanc

PHPのみ"0"または空の文字列がfalseに強制されます。他のすべての空でない文字列は、強制的にtrueになります。 manual から:

ブール値に変換する場合、次の値はFALSEと見なされます。

  • 空の文字列、および文字列「0」

文字列"true" vs "false"を処理する独自の関数を作成する必要があります。ここでは、他のすべてがデフォルトでfalseであると仮定しています。

function isBoolean($value) {
   if ($value === "true") {
      return true;
   } else {
      return false;
   }
}

簡単に凝縮できるサイドノート

function isBoolean($value) {
   return $value === "true";
}
5
BoltClock

私は最近、(特に)質問しているような文字列を処理するための「ゆるい」ブール変換関数が必要でした。 私はいくつかの異なるアプローチを見つけ、それらを実行するためのテストデータの大きなセットを思い付きました 。私のニーズに合うものは何もないので、私は自分で書いた:

function loosely_cast_to_boolean($value) {
    if(is_array($value) || $value instanceof Countable) {
        return (boolean) count($value);
    } else if(is_string($value) || is_object($value) && method_exists($value, '__toString')) {
        $value = (string) $value;
        // see http://www.php.net/manual/en/filter.filters.validate.php#108218
        // see https://bugs.php.net/bug.php?id=49510
        $filtered = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
        if(!is_null($filtered)) {
            return $filtered;
        } else {
            // "none" gets special treatment to be consistent with ini file behavior.
            // see documentation in php.ini for more information, in part it says: 
            // "An empty string can be denoted by simply not writing anything after 
            // the equal sign, or by using the None keyword".
            if(strtolower($value) === 'none') {
                $value = '';
            }
            return (boolean) $value;
        }
    } else {
        return (boolean) $value;
    }
}

カウント可能かつ文字列キャスト可能なオブジェクトの場合、これは文字列値よりもカウントを優先して真実性を判断することに注意してください。つまり、$object instanceof Countableの場合、(boolean) count($object)の値に関係なく(string) $objectを返します。

使用したテストデータの動作と、他のいくつかの関数 here の結果を確認できます。その小さなiframeの結果をざっと読むのはちょっと難しいので、代わりに スクリプト出力を全ページで表示 にすることができます(URLはドキュメント化されていないので、これは永久に機能しないかもしれません)。これらのリンクがいつか死ぬ場合、 Pastebinにコードを配置します も同様です。

「本来あるべき」ものとそうでないものとの間の線は、かなりarbitrary意的です。私が使用したデータは、私のニーズと美的好みに基づいて分類されていますが、あなたのデータは異なる場合があります。

4
Matt Kantor

他のほとんどの値にtrueが必要なため、このコンストラクトを使用して文字列をブール値に変換しています。

$str = "true";
$bool = !in_array($str, array("false", "", "0", "no", "off"));
3
mario

「true」と「false」の文字列をブール値に解析する関数はPHPにありますか?

いいえ-両方とも文字列であり、両方とも(あなたが言うように)trueと評価されます。 PHPでは、空の文字列のみがfalseと評価されます。

これを手動でテストする必要があります。ただし、可能な場合は、代わりに「実際の」ブール値を使用することをお勧めします。

1
Pekka 웃

安全にブール値に変換する最も簡単な方法。

    $flag = 'true';

    if( filter_var( $flag,FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ) !== null) {
      $flag = filter_var($flag,FILTER_VALIDATE_BOOLEAN);
    }

    gettype($flag); // Would Return 'Boolean'
    echo 'Val: '.$flag; // Would Output 'Val: 1'
0
Timothy Perez