Melhor maneira de verificar variável para seqüência nula ou vazia?

174

Como o PHP é uma linguagem dinâmica, qual é a melhor maneira de verificar se um campo fornecido está vazio?

Eu quero garantir que:

  1. null é considerado uma string vazia
  2. uma única string de espaço em branco é considerada vazia
  3. que "0" não é considerado vazio

Isto é o que eu tenho até agora:

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

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

Deve haver uma maneira mais simples de fazer isso?

Allain Lalonde
fonte
1
Eu diria para usar vazio ($ question), mas isso também considera 0 como vazio.
Powerlord 19/12/08
2
condições Yoda são horrendo
user3791372

Respostas:

278
// Function for basic field validation (present and neither empty nor only white space
function IsNullOrEmptyString($str){
    return (!isset($str) || trim($str) === '');
}
Michael Haren
fonte
7
Embora isso resolva, não tenho certeza se é mais simples. +1 de qualquer maneira
Allain Lalonde
4
Como o OP está pedindo uma versão 'mais simples' de uma operação extremamente simples, vou dizer que 'melhor' é o que é realmente necessário.
caos
2
Eu transformei isso em uma função. isso deve fazer o código de validação mais simples
Michael Haren
7
qual é o objetivo de! isset () aqui? como é diferente is_null ()?
nickf
2
também return (! empty ($ question) || trim ($ question) === '');
SpYk3HH
109

Post antigo, mas alguém pode precisar dele como eu;)

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

substitua $strpor sua variável. NULLe ""ambos retornam 0 ao usar strlen.

jrowe
fonte
4
E sempre tem:if(strcmp('', $var) == 0)...
peter
12
Por que == 0 e não apenas se (strlen ($ str))?
Númeno
14
@Noumenon Porque isso prejudicaria a legibilidade sem resolver nada. É muito fácil ler sua sugestão como "se houver um comprimento", enquanto (é claro) significa o contrário.
Mattias Åslund
11
Não vai ajudar para string com espaços somente, se alguém se preocupa para que
AIRBOSS
5
Se a variável não está definida, isto produzirá um aviso
Konstantin Pereiaslov
25

Use a função empty () do PHP. Os seguintes itens são considerados vazios

"" (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 mais detalhes, verifique a função vazia

kta
fonte
7
O pôster disse que eles NÃO querem considerar o "0" vazio
dougd_in_nc 20/11/19
18

Aceito humildemente se estiver errado, mas testei por conta própria e descobri que o seguinte funciona para testar as variáveis ​​de valor string (0) "" e NULL:

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

O que também pode ser revertido para testar o sucesso como tal:

if ( !$question ) {
  // Handle error here
}
Adal
fonte
posso sugerir "if (trim ($ n)) .." caso contrário, se um $ _POST var (por exemplo) for simplesmente "", seria considerado válido, enquanto que, na maioria dos casos, é tão bom quanto uma string vazia
Você está em: Home
Se "" não for um valor aceitável para uma função específica, usar o trim será uma ótima idéia.
Adal
3
Isso retornará false para "0", numérico 0 ou 0,0 e FALSE.
Vedmant
7

Cuidado com os falsos negativos da trim()função - ela executa uma conversão para string antes de aparar e, portanto, retornará, por exemplo, "Array" se você passar uma matriz vazia. Isso pode não ser um problema, dependendo de como você processa seus dados, mas com o código que você fornece, um campo nomeado question[]pode ser fornecido nos dados do POST e parece ser uma sequência não vazia. Em vez disso, eu sugeriria:

$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
fonte
Eu diria que se você obtiver uma matriz em que você espera uma string, isso deve ser um erro. Se você espera uma matriz, deve ter uma função de filtragem separada para isso.
OIS
Esse código não está tratando isso como um erro? Se a filtragem for feita em outro lugar, deve-se tomar cuidado para não duplicar o conhecimento das regras de validação dos argumentos em lugares separados.
grantwparks
3

Não há maneira melhor, mas como é uma operação que você costuma fazer com bastante frequência, é melhor automatizar o processo.

A maioria das estruturas oferece uma maneira de tornar os argumentos de análise uma tarefa fácil. Você pode criar seu próprio objeto para isso. Exemplo rápido e sujo:

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 esse tipo de açúcar em massa.

Mas você está falando mais do que isso, com o seu "// Manipular erro aqui". Você está misturando 2 trabalhos: obtendo e processando os dados. Isto não é o mesmo.

Existem outros mecanismos que você pode usar para validar dados. Novamente, os frameworks podem mostrar as melhores práticas.

Crie objetos que representam os dados do seu formulário, anexe processos e volte a ele. Parece muito mais trabalho do que invadir um script PHP rápido (e é a primeira vez), mas é reutilizável, flexível e muito menos suscetível a erros, pois a validação de formulários com o PHP comum tende a se tornar rapidamente um código espaguete.

e-satis
fonte
21
Você fez exatamente o oposto do que ele queria ... simplicidade.
TravisO 20/12/08
2

Este verifica matrizes e seqüências de caracteres:

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

  return strlen(trim($val)) ? true : false;
}
Chris Clower
fonte
Não é ruim. A resposta do PHPst faz o mesmo, mas de forma mais concisa.
Allain Lalonde
2

para ser mais robusto (tabulação, retorno ...), eu 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");
}

fontes:

bcag2
fonte
1

Quando você deseja verificar se um valor é fornecido para um campo, esse campo pode ser um string, um arrayou não definido. Então, o seguinte é suficiente

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

empty () costumava trabalhar para isso, mas o comportamento de empty () mudou várias vezes. Como sempre, os documentos php são sempre a melhor fonte para o comportamento exato e os comentários nessas páginas geralmente fornecem um bom histórico das alterações ao longo do tempo. Se você deseja verificar a falta de propriedades do objeto, um método muito defensivo no momento é:

if (is_object($theObject) && (count(get_object_vars($theObject)) > 0)) {
NJInamdar
fonte