Analizando una cadena en un valor booleano en PHP

126

Hoy estaba jugando con PHP, y descubrí que los valores de cadena "verdadero" y "falso" no se analizan correctamente como booleanos en una condición, por ejemplo, considerando la siguiente función:

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

Si ejecuto:

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

Parece que solo funciona con los valores "1" y "0":

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

¿Hay una función nativa en PHP para analizar cadenas "verdaderas" y "falsas" en booleano?

marca
fuente
En su código, isBoolean("")debe devolver falso.
BoltClock
Debería considerar cambiar la respuesta aceptada a la respuesta de Eric Caron. Le muestra una función nativa que hace lo que le pide.
Code Commander el
1
PHP no piensa en lo que dice la cadena, "falso" son solo cinco caracteres que no significan nada. Sin embargo, son algo , por lo que el valor booleano se evalúa trueaunque, para un lector humano, parezca más intuitivo de lo que significaba FALSE.
zeel

Respuestas:

413

Hay un método PHP nativo para hacer esto que usa el método filter_var de PHP:

$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN);

De acuerdo con el manual de PHP :

Devuelve TRUE para "1", "true", "on" y "yes". Devuelve FALSO de lo contrario.

Si se establece FILTER_NULL_ON_FAILURE, FALSE se devuelve solo para "0", "false", "off", "no" y "", y se devuelve NULL para todos los valores no booleanos.

Eric Caron
fuente
Esta debería haber sido la respuesta aceptada. Las funciones PHP integradas son mejores que crear las suyas propias. ¡No hay necesidad de reinventar la rueda! Lástima que fuera demasiado tarde: P
casraf
1
¿también minúscula el valor para la comparación?
Mobiletainment
3
@Mobiletainment, sí, maneja cualquier carcasa que puedas imaginar por $ valor (falso, FALSO, Falso, etc.)
Eric Caron el
Borked testcase de mi lado. Usado == en lugar de === para la comparación. Eliminaré mi comentario anterior para no confundir a las personas.
andig
66
La respuesta me tomó por sorpresa porque tienes que agregar la bandera FILTER_NULL_ON_FAILUREa la filter_var()función y NO reemplazarla FILTER_VALIDATE_BOOLEANcomo pensé. Esto dará como resultado el siguiente código que hizo el truco para mí:$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)
Dragon54
14

La razón es que todas las cadenas se evalúan truecuando se convierten en booleanas, excepto "0"y ""(cadena vacía).

La siguiente función hará exactamente lo que desea: se comporta exactamente como PHP, pero también evalúa la cadena "false"como false:

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

La documentación explica que: http://php.net/manual/en/language.types.boolean.php :

Al convertir a booleano, los siguientes valores se consideran FALSOS:

  • el booleano FALSO
  • el entero 0 (cero)
  • el flotador 0.0 (cero)
  • la cadena vacía y la cadena "0"
  • una matriz con cero elementos
  • el tipo especial NULL (incluidas las variables no definidas)
  • Objetos SimpleXML creados a partir de etiquetas vacías

Cualquier otro valor se considera VERDADERO (incluido cualquier recurso).

Arnaud Le Blanc
fuente
2
+1 Niza. (Podría arrojar un strtolower allí, pero eso es todo.)
John Parker
Creo que middaparka significaba comparar strtolower ($ value) con 'false'. Pasar un literal 'falso' en strtolower es un poco ... tonto? :)
Paul Dixon
@Paul Dixon Sí, a eso me refería. :-)
John Parker el
2
@Marco - if ($ value && strtolower ($ value)! == "faux") {si está trabajando en francés; if ($ value && strtolower ($ value)! == "falsch") {en alemán; if ($ value && strtolower ($ value)! == "onwaar") {en holandés ... puedes entender por qué PHP no tiene esto integrado como estándar
Mark Baker
1
"todas las cadenas no vacías se evalúan como verdaderas al convertirlas a booleanas, excepto" 0 "."
BoltClock
5

Solo en PHP "0"o la cadena vacía coacciona a falso; cualquier otra cadena no vacía coacciona a verdadero. Del manual :

Al convertir a booleano, se consideran los siguientes valores FALSE:

  • la cadena vacía y la cadena "0"

Usted tiene que escribir su propia función para manejar las cuerdas "true"vs "false". Aquí, supongo que todo lo demás por defecto es falso:

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

En una nota al margen que fácilmente podría condensarse en

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

Hace poco necesitaba una función de conversión booleana "suelta" para manejar cadenas como las que está preguntando (entre otras cosas). Encontré algunos enfoques diferentes y se me ocurrió un gran conjunto de datos de prueba para ejecutarlos . Nada se ajusta a mis necesidades, así que escribí el mío:

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

Tenga en cuenta que para los objetos que son contables y moldeables en cadena, esto favorecerá el recuento sobre el valor de la cadena para determinar la veracidad. Es decir, si $object instanceof Countableesto regresará (boolean) count($object)independientemente del valor de (string) $object.

Puede ver el comportamiento de los datos de prueba que utilicé, así como los resultados de varias otras funciones aquí . Es un poco difícil leer los resultados de ese pequeño iframe, por lo que puede ver la salida del script en una página completa (esa URL no está documentada, por lo que esto podría no funcionar para siempre). En caso de que esos enlaces desaparezcan algún día, también pongo el código en pastebin .

La línea entre lo que "debería ser cierto" y lo que no debería es bastante arbitraria; Los datos que utilicé se clasifican en función de mis necesidades y preferencias estéticas, las suyas pueden diferir.

Matt Kantor
fuente
Esta función funciona a la perfección, ¡gracias! Pero sus enlaces ahora son 404.
servermanfail
3

Estoy usando esta construcción para transformar cadenas en booleanos, ya que desea truepara la mayoría de los otros valores:

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

¿Hay una función en PHP para analizar cadenas "verdaderas" y "falsas" en booleano?

No, ambas son cadenas y ambas (como usted dice) evalúan true. Solo las cadenas vacías se evalúan falseen PHP.

Tendría que probar esto manualmente. Sin embargo, si es posible, sería mejor trabajar con valores booleanos "reales".

Pekka
fuente
1
No todas las cadenas se evalúan trueen PHP.
coreyward
1
No estaba corrigiendo, solo aclarando. Decir "ambos son cadenas [y evaluar a true]" podría dar a un novato la impresión equivocada, especialmente una de otro idioma con reglas de escritura más estrictas donde una cadena es una cadena y el contenido no importa cuando se convierte en un booleano (como Rubí).
coreyward
1
"Solo las cadenas vacías se evalúan como falsas en PHP". Pero, ¿qué pasa con la cadena no vacía "0"? ¿No se evalúa esto también false?
Sepster
0

La forma más fácil de convertir de forma segura a un booleano;

    $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'
Timothy Perez
fuente
0

Si su API solo acepta las cadenas "verdadero" o "falso", con todo lo demásnull , intente:

$boolean = ['true' => true, 'false' => false][$inputString] ?? null;

Esto supone que $inputno es un objeto. Null coalesce ( ??) se introdujo en PHP 7.0.

Matt Janssen
fuente