¿Mejor manera de verificar la variable para una cadena nula o vacía?


174

Dado que PHP es un lenguaje dinámico, ¿cuál es la mejor manera de verificar si un campo proporcionado está vacío?

Quiero asegurarme de que:

  1. nulo se considera una cadena vacía
  2. una cadena de solo espacio en blanco se considera vacía
  3. que "0" no se considera vacío

Esto es lo que tengo hasta ahora:

$question = trim($_POST['question']);

if ("" === "$question") {
    // Handle error here
}

Debe haber una manera más simple de hacer esto?


1
Yo diría que use empty ($ question), pero eso también considera que 0 está vacío.
Powerlord

2
las condiciones de yoda son horribles
user3791372

Respuestas:


278
// Function for basic field validation (present and neither empty nor only white space
function IsNullOrEmptyString($str){
    return (!isset($str) || trim($str) === '');
}

77
Aunque esto lo resuelve, no estoy seguro de si es más simple. +1 de todos modos
Allain Lalonde

44
Dado que OP está pidiendo una versión 'más simple' de una operación extremadamente simple, voy a decir que 'mejor' es lo que realmente está garantizado.
caos

2
Lo convertí en una función. esto debería simplificar su código de validación
Michael Haren

77
¿Cuál es el propósito de! isset () aquí? ¿Cómo es diferente a is_null ()?
nickf

2
también return (! empty ($ question) || trim ($ question) === '');
SpYk3HH

109

Publicación anterior pero alguien podría necesitarla como yo;)

if (strlen($str) == 0){
do what ever
}

reemplace $strcon su variable. NULLy ""ambos devuelven 0 cuando se usa strlen.


44
Y siempre hay:if(strcmp('', $var) == 0)...
peter

12
¿Por qué == 0 y no solo si (strlen ($ str))?
Noumenon

14
@Noumenon Porque eso perjudicaría la legibilidad sin resolver nada. Es realmente fácil leer su sugerencia como "si hay una longitud" mientras que (por supuesto) significa lo contrario.
Mattias Åslund

11
No será de ayuda solo para cadenas con espacios, si a alguien le importa eso
airboss

55
Si no se establece la variable, esto generará una advertencia
Konstantin Pereiaslov

25

Use la función empty () de PHP. Las siguientes cosas se consideran vacías.

"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
$var; (a variable declared, but without a value)

Para más detalles verifique la función vacía


77
Poster dijo que NO quieren considerar "0" vacío
dougd_in_nc

18

Aceptaré humildemente si me equivoco, pero lo probé por mi cuenta y descubrí que lo siguiente funciona para probar las variables de valor string (0) "" y NULL:

if ( $question ) {
  // Handle success here
}

Lo que también podría revertirse para probar el éxito como tal:

if ( !$question ) {
  // Handle error here
}

¿puedo sugerir "if (trim ($ n)) .." de lo contrario si un $ _POST var (por ejemplo) es simplemente "", se consideraría válido, mientras que, en la mayoría de los casos, esto es tan bueno como una cadena vacía
StartupGuy

Si "" no es un valor aceptable para una función específica, sería una buena idea usar trim.
Adal

3
Esto devolverá falso para "0", numérico 0 o 0.0 y FALSO.
Vedmant

7

Tenga cuidado con los falsos negativos de la trim()función: realiza una conversión de cadena a cadena antes de recortar y, por lo tanto, devolverá, por ejemplo, "Array" si le pasa una matriz vacía. Es posible que eso no sea un problema, dependiendo de cómo procese sus datos, pero con el código que proporciona, un campo denominado question[]podría proporcionarse en los datos POST y parecer una cadena no vacía. En cambio, sugeriría:

$question = $_POST['question'];

if (!is_string || ($question = trim($question))) {
    // Handle error here
}

// If $question was a string, it will have been trimmed by this point

Diría que si obtiene una matriz donde esperaba una cadena, debería ser un error. Si espera una matriz, entonces debe tener una función de filtrado separada para eso.
OIS

¿Ese código no lo trata como un error? Si el filtrado se realiza en otro lugar, se debe tener cuidado de no duplicar el conocimiento de las reglas de validación de los argumentos en lugares separados.
grantwparks

3

No hay mejor manera, pero como es una operación que generalmente haces con bastante frecuencia, será mejor que automatices el proceso.

La mayoría de los marcos ofrecen una manera de hacer que el análisis de argumentos sea una tarea fácil. Puedes construir tu propio objeto para eso. Ejemplo rápido y sucio:

class Request
{

    // This is the spirit but you may want to make that cleaner :-)
    function get($key, $default=null, $from=null)
    {
         if ($from) :
             if (isset(${'_'.$from}[$key]));
                return sanitize(${'_'.strtoupper($from)}[$key]); // didn't test that but it should work
         else
             if isset($_REQUEST[$key])
                return sanitize($_REQUEST[$key]);

         return $default;
    }

    // basics. Enforce it with filters according to your needs
    function sanitize($data)
    {
          return addslashes(trim($data));
    }

    // your rules here
    function isEmptyString($data)
    {
        return (trim($data) === "" or $data === null);
    }


    function exists($key) {}

    function setFlash($name, $value) {}

    [...]

}

$request = new Request();
$question= $request->get('question', '', 'post');
print $request->isEmptyString($question);

Symfony usa ese tipo de azúcar de forma masiva.

Pero está hablando de más que eso, con su "// Manejar error aquí". Está mezclando 2 trabajos: obtener los datos y procesarlos. Esto no es lo mismo en absoluto.

Existen otros mecanismos que puede usar para validar datos. Una vez más, los marcos pueden mostrarle las mejores prácticas.

Cree objetos que representen los datos de su formulario, luego adjunte procesos y recurra a ellos. Suena mucho más trabajo que piratear un script PHP rápido (y es la primera vez), pero es reutilizable, flexible y mucho menos propenso a errores, ya que la validación de formularios con PHP habitual tiende a convertirse rápidamente en código spaguetti.


21
Hiciste exactamente lo contrario de lo que él quería ... simplicidad.
TravisO

2

Éste verifica matrices y cadenas:

function is_set($val) {
  if(is_array($val)) return !empty($val);

  return strlen(trim($val)) ? true : false;
}

No está mal. La respuesta de PHPst hace lo mismo pero de manera más concisa.
Allain Lalonde

2

para ser más robusto (tabulación, retorno ...), defino:

function is_not_empty_string($str) {
    if (is_string($str) && trim($str, " \t\n\r\0") !== '')
        return true;
    else
        return false;
}

// code to test
$values = array(false, true, null, 'abc', '23', 23, '23.5', 23.5, '', ' ', '0', 0);
foreach ($values as $value) {
    var_export($value);
    if (is_not_empty_string($value)) 
        print(" is a none empty string!\n");
    else
        print(" is not a string or is an empty string\n");
}

fuentes:


1

Cuando desee comprobar si se proporciona un valor para un campo, ese campo puede ser a string, an arrayo no definido. Entonces, lo siguiente es suficiente

function isSet($param)
{
    return (is_array($param) && count($param)) || trim($param) !== '';
}

0

empty () solía funcionar para esto, pero el comportamiento de empty () ha cambiado varias veces. Como siempre, los documentos php son siempre la mejor fuente de comportamiento exacto y los comentarios en esas páginas generalmente proporcionan un buen historial de los cambios a lo largo del tiempo. Si desea verificar la falta de propiedades del objeto, un método muy defensivo en este momento es:

if (is_object($theObject) && (count(get_object_vars($theObject)) > 0)) {
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.