web-dev-qa-db-fra.com

Analyser une chaîne en une valeur booléenne dans PHP

Aujourd'hui, je jouais avec PHP et j'ai découvert que les valeurs de chaîne "true" et "false" ne sont pas correctement analysées comme boolean dans une condition, par exemple si l'on considère la fonction suivante:

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

Si j'exécute:

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

Cela ne semble fonctionner qu'avec les valeurs "1" et "0":

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

Existe-t-il une fonction native dans PHP pour analyser les chaînes "true" et "false" en boolean?)

115
Mark

Il existe une méthode native PHP) qui utilise la méthode filter_var de PHP:

$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN);

Selon manuel PHP :

Retourne TRUE pour "1", "true", "on" et "yes". Retourne FALSE sinon.

Si FILTER_NULL_ON_FAILURE est défini, FALSE est renvoyé uniquement pour "0", "false", "off", "no" et "", et NULL est renvoyé pour toutes les valeurs non booléennes.

381
Eric Caron

La raison en est que toutes les chaînes sont évaluées en true lors de leur conversion en booléen, à l'exception de "0" et "" (chaîne vide).

La fonction suivante fera exactement ce que vous voulez: elle se comporte exactement comme PHP, mais évaluera également la chaîne "false" comme false:

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

La documentation explique que: http://php.net/manual/en/language.types.boolean.php :

Lors de la conversion en booléen, les valeurs suivantes sont considérées comme FALSE:

  • le booléen FAUX lui-même
  • le nombre entier 0 (zéro)
  • le flottant 0.0 (zéro)
  • la chaîne vide, et la chaîne "0"
  • un tableau avec zéro élément
  • le type spécial NULL (y compris les variables non définies)
  • Objets SimpleXML créés à partir de balises vides

Toute autre valeur est considérée comme VRAIE (y compris les ressources).

14
Arnaud Le Blanc

Dans PHP seulement "0" ou la chaîne vide contraint à false; chaque autre chaîne non vide est forcée à true. Du manuel :

Lors de la conversion en booléen, les valeurs suivantes sont considérées comme FALSE:

  • la chaîne vide et la chaîne "0"

Vous devez écrire votre propre fonction pour gérer les chaînes "true" contre "false". Ici, je suppose que tout le reste par défaut est faux:

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

Sur une note de côté qui pourrait facilement être condensé à

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

J'ai récemment eu besoin d'une fonction de conversion booléenne "en vrac" pour gérer les chaînes comme celles que vous demandez (entre autres). J'ai trouvé quelques approches différentes et mis au point un grand ensemble de données de test pour les parcourir . Rien ne correspondant à mes besoins, j'ai donc écrit le mien:

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;
    }
}

Notez que pour les objets à la fois dénombrables et convertibles en chaînes, cela favorise le décompte par rapport à la valeur de chaîne afin de déterminer la vérité. Autrement dit, si $object instanceof Countable ceci retournera (boolean) count($object) quelle que soit la valeur de (string) $object.

Vous pouvez voir le comportement des données de test que j'ai utilisées ainsi que les résultats de plusieurs autres fonctions ici . Il est assez difficile de survoler les résultats de cette petite iframe, vous pouvez donc afficher le résultat du script sur une page entière , à la place (cette URL n'est pas documentée et ne fonctionnera donc pas indéfiniment). Au cas où ces liens mourraient un jour, j'ai mis le code sur Pastebin également.

La ligne de démarcation entre ce qui "devrait être vrai" et ce qui ne devrait pas être est assez arbitraire; Si les données que j'ai utilisées sont classées par catégories en fonction de mes besoins et de mes préférences esthétiques, les vôtres peuvent différer.

4
Matt Kantor

J'utilise cette construction pour transformer des chaînes en booléens, car vous voulez true pour la plupart des autres valeurs:

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

Existe-t-il une fonction dans PHP) pour analyser les chaînes "true" et "false" en boolean?

Non - les deux sont des chaînes, et celles-ci (comme vous le dites) évaluent true. Seules les chaînes vides sont évaluées à false en PHP.

Vous auriez besoin de tester cela manuellement. Si possible, il serait préférable de travailler avec de "vraies" valeurs booléennes.

1
Pekka 웃

Meilleure façon de convertir en toute sécurité en un booléen;

    $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