¿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?

Allain Lalonde
fuente
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) === '');
}
Michael Haren
fuente
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.

jrowe
fuente
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

kta
fuente
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
}
Adal
fuente
¿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
Ben Blank
fuente
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.

e-satis
fuente
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;
}
Chris Clower
fuente
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:

bcag2
fuente
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) !== '';
}
PHPst
fuente
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)) {
NJInamdar
fuente