Meilleur moyen de vérifier la variable pour une chaîne nulle ou vide?

174

Puisque PHP est un langage dynamique, quelle est la meilleure façon de vérifier si un champ fourni est vide?

Je veux m'assurer que:

  1. null est considéré comme une chaîne vide
  2. une chaîne d'espace blanc uniquement est considérée comme vide
  3. que "0" n'est pas considéré comme vide

Voici ce que j'ai jusqu'à présent:

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

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

Il doit y avoir un moyen plus simple de faire cela?

Allain Lalonde
la source
1
Je dirais d'utiliser vide ($ question), mais cela considère également que 0 est vide.
Powerlord
2
Les conditions yoda sont horribles
user3791372

Réponses:

278
// Function for basic field validation (present and neither empty nor only white space
function IsNullOrEmptyString($str){
    return (!isset($str) || trim($str) === '');
}
Michael Haren
la source
7
Bien que cela résout le problème, je ne suis pas sûr que ce soit plus simple. +1 quand même
Allain Lalonde
4
Puisque OP demande une version «plus simple» d'une opération extrêmement simple, je vais dire que «mieux» est ce qui est réellement justifié.
chaos
2
Je l'ai transformé en fonction. cela devrait rendre votre code de validation plus simple
Michael Haren
7
quel est le but de! isset () ici? en quoi est-ce différent de is_null ()?
nickf
2
aussi return (! vide ($ question) || trim ($ question) === '');
SpYk3HH
109

Ancien message mais quelqu'un pourrait en avoir besoin comme moi;)

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

remplacez $strpar votre variable. NULLet les ""deux renvoient 0 lors de l'utilisation strlen.

jrowe
la source
4
Et il y a toujours:if(strcmp('', $var) == 0)...
peter
12
Pourquoi == 0 et pas seulement if (strlen ($ str))?
Noumenon
14
@Noumenon Parce que cela nuirait à la lisibilité sans rien résoudre. Il est très facile de lire votre suggestion comme "s'il y a une longueur" alors que cela signifie (bien sûr) le contraire.
Mattias Åslund
11
N'aidera pas pour la chaîne avec des espaces uniquement, si quelqu'un s'en soucie
airboss
5
Si la variable n'est pas définie, cela produira un avertissement
Konstantin Pereiaslov
25

Utilisez la fonction empty () de PHP. Les éléments suivants sont considérés comme vides

"" (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)

Pour plus de détails, vérifiez la fonction vide

kta
la source
7
L'affiche a dit qu'ils NE
VEUX
18

J'accepterai humblement si je me trompe, mais j'ai testé de mon côté et j'ai trouvé que ce qui suit fonctionne pour tester à la fois les variables de valeur string (0) "" et NULL:

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

Ce qui pourrait également être inversé pour tester le succès en tant que tel:

if ( !$question ) {
  // Handle error here
}
Adal
la source
puis-je suggérer "if (trim ($ n)) .." sinon si un $ _POST var (par exemple) est simplement "", il serait considéré comme valide, alors que, dans la plupart des cas, c'est aussi bon qu'une chaîne vide
StartupGuy
Si "" n'est pas une valeur acceptable pour une fonction spécifique, l'utilisation de trim serait une excellente idée.
Adal
3
Cela renverra faux pour «0», numérique 0 ou 0,0 et FALSE.
Vedmant le
7

Méfiez-vous des faux négatifs de la trim()fonction - elle effectue un transtypage en chaîne avant le découpage, et retournera donc par exemple "Array" si vous lui passez un tableau vide. Cela peut ne pas être un problème, selon la façon dont vous traitez vos données, mais avec le code que vous fournissez, un champ nommé question[]peut être fourni dans les données POST et apparaître comme une chaîne non vide. Au lieu de cela, je suggérerais:

$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
la source
Id dire que si vous obtenez un tableau où vous attendiez une chaîne, cela devrait être une erreur. Si vous attendez un tableau, vous devriez avoir une fonction de filtrage distincte pour cela.
OIS
Ce code ne le traite-t-il pas comme une erreur? Si le filtrage est effectué ailleurs, il faudrait veiller à ne pas dupliquer la connaissance des règles de validation des arguments dans des endroits séparés.
grantwparks
3

Il n'y a pas de meilleur moyen, mais comme c'est une opération que vous faites généralement assez souvent, vous feriez mieux d'automatiser le processus.

La plupart des frameworks offrent un moyen de rendre l'analyse des arguments une tâche facile. Vous pouvez créer votre propre objet pour cela. Exemple rapide et sale:

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 utilise massivement ce type de sucre.

Mais vous parlez de plus que cela, avec votre "// Handle error here". Vous mélangez 2 jobs: récupérer les données et les traiter. Ce n'est pas du tout la même chose.

Il existe d'autres mécanismes que vous pouvez utiliser pour valider les données. Encore une fois, les frameworks peuvent vous montrer les meilleures pratiques.

Créez des objets qui représentent les données de votre formulaire, puis attachez des processus et revenez dessus. Cela semble beaucoup plus de travail que de pirater un script PHP rapide (et c'est la première fois), mais c'est réutilisable, flexible et beaucoup moins sujet aux erreurs puisque la validation de formulaire avec PHP habituel a tendance à devenir rapidement du code spaguetti.

e-satis
la source
22
Vous avez fait exactement le contraire de ce qu'il voulait ... la simplicité.
TravisO
2

Celui-ci vérifie les tableaux et les chaînes:

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

  return strlen(trim($val)) ? true : false;
}
Chris Clower
la source
Pas mal. La réponse de PHPst fait la même chose, mais de manière plus concise.
Allain Lalonde
2

pour être plus robuste (tabulation, retour…), je définis:

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

sources:

bcag2
la source
1

Lorsque vous souhaitez vérifier si une valeur est fournie pour un champ, ce champ peut être a string, an arrayou non défini. Donc, ce qui suit suffit

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

empty () fonctionnait pour cela, mais le comportement de empty () a changé plusieurs fois. Comme toujours, les documents php sont toujours la meilleure source de comportement exact et les commentaires sur ces pages fournissent généralement un bon historique des changements au fil du temps. Si vous voulez vérifier l'absence de propriétés d'objet, une méthode très défensive pour le moment est:

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