Besserer Weg, um Variablen auf null oder leere Zeichenfolge zu überprüfen?

173

Da PHP eine dynamische Sprache ist, wie kann am besten überprüft werden, ob ein bereitgestelltes Feld leer ist?

Ich möchte sicherstellen, dass:

  1. null wird als leere Zeichenfolge betrachtet
  2. Eine Zeichenfolge, die nur aus Leerzeichen besteht, wird als leer betrachtet
  3. dass "0" nicht als leer betrachtet wird

Das habe ich bisher:

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

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

Es muss einen einfacheren Weg geben, dies zu tun?

Allain Lalonde
quelle
1
Ich würde sagen, leer zu verwenden ($ question), aber das betrachtet auch 0 als leer.
Powerlord
2
yoda Bedingungen sind schrecklich
user3791372

Antworten:

277
// Function for basic field validation (present and neither empty nor only white space
function IsNullOrEmptyString($str){
    return (!isset($str) || trim($str) === '');
}
Michael Haren
quelle
7
Obwohl dies das Problem löst, bin ich mir nicht sicher, ob es einfacher ist. +1 sowieso
Allain Lalonde
4
Da OP nach einer "einfacheren" Version einer extrem einfachen Operation fragt, werde ich sagen, dass "besser" tatsächlich gerechtfertigt ist.
Chaos
2
Ich habe daraus eine Funktion gemacht. Dies sollte Ihren Validierungscode vereinfachen
Michael Haren
7
Was ist der Zweck von! isset () hier? Wie unterscheidet es sich von is_null ()?
Nickf
2
auch return (! empty ($ question) || trim ($ question) === '');
SpYk3HH
109

Alter Beitrag, aber jemand könnte ihn so brauchen wie ich;)

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

durch $strdeine Variable ersetzen . NULLund ""beide geben bei Verwendung 0 zurück strlen.

jrowe
quelle
4
Und es gibt immer:if(strcmp('', $var) == 0)...
Peter
12
Warum == 0 und nicht nur wenn (strlen ($ str))?
Noumenon
14
@ Noumenon Weil dies die Lesbarkeit beeinträchtigen würde, ohne etwas zu lösen. Es ist wirklich einfach, Ihren Vorschlag als "wenn es eine Länge gibt" zu lesen, während er (natürlich) das Gegenteil bedeutet.
Mattias Åslund
10
Hilft
4
Wenn die Variable nicht gesetzt ist, wird eine Warnung
ausgegeben
26

Verwenden Sie die leere () Funktion von PHP. Die folgenden Dinge gelten als leer

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

Für weitere Details überprüfen Sie die leere Funktion

kta
quelle
6
Poster sagte, dass sie "0" NICHT als leer betrachten wollen
dougd_in_nc
19

Ich werde demütig akzeptieren, wenn ich falsch liege, aber ich habe es selbst getestet und festgestellt, dass das Folgende zum Testen von Variablen mit Zeichenfolgen (0) "" und NULL funktioniert:

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

Was auch umgekehrt werden könnte, um den Erfolg als solchen zu testen:

if ( !$question ) {
  // Handle error here
}
Adal
quelle
Darf ich "if (trim ($ n)) .." vorschlagen, andernfalls, wenn eine $ _POST-Variable (zum Beispiel) einfach "" ist, wird sie als gültig angesehen, während dies in den meisten Fällen so gut ist wie eine leere Zeichenfolge
StartupGuy
Wenn "" für eine bestimmte Funktion kein akzeptabler Wert ist, ist die Verwendung von trim eine gute Idee.
Adal
2
Dies gibt false für "0", numerisch 0 oder 0.0 und FALSE zurück.
Vedmant
7

Hüten Sie sich vor falschen Negativen aus der trim()Funktion - sie führt vor dem Zuschneiden eine Umwandlung in einen String durch und gibt daher z. B. "Array" zurück, wenn Sie ein leeres Array übergeben. Dies ist möglicherweise kein Problem, je nachdem, wie Sie Ihre Daten verarbeiten. Mit dem von Ihnen angegebenen Code kann jedoch ein Feld mit dem Namen question[]in den POST-Daten angegeben werden und scheint eine nicht leere Zeichenfolge zu sein. Stattdessen würde ich vorschlagen:

$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
quelle
Ich würde sagen, wenn Sie ein Array erhalten, in dem Sie eine Zeichenfolge erwartet haben, sollte dies ein Fehler sein. Wenn Sie ein Array erwarten, sollten Sie dafür eine separate Filterfunktion haben.
OIS
Behandelt dieser Code ihn nicht als Fehler? Wenn an anderer Stelle gefiltert wird, muss darauf geachtet werden, dass das Wissen über die Validierungsregeln der Argumente nicht an verschiedenen Stellen dupliziert wird.
Grantwparks
3

Es gibt keinen besseren Weg, aber da es sich um eine Operation handelt, die Sie normalerweise häufig ausführen, sollten Sie den Prozess besser automatisieren.

Die meisten Frameworks bieten eine Möglichkeit, das Parsen von Argumenten zu einer einfachen Aufgabe zu machen. Sie können dafür ein eigenes Objekt erstellen. Schnelles und schmutziges Beispiel:

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 verwendet diese Art von Zucker massiv.

Aber Sie sprechen über mehr als das, mit Ihrem "// Fehler hier behandeln". Sie mischen zwei Jobs: Abrufen und Verarbeiten der Daten. Das ist überhaupt nicht dasselbe.

Es gibt andere Mechanismen, mit denen Sie Daten validieren können. Auch hier können Frameworks Ihnen die besten Praktiken zeigen.

Erstellen Sie Objekte, die die Daten Ihres Formulars darstellen, hängen Sie dann Prozesse an und greifen Sie darauf zurück. Es klingt viel mehr Arbeit als das Hacken eines schnellen PHP-Skripts (und es ist das erste Mal), aber es ist wiederverwendbar, flexibel und viel weniger fehleranfällig, da die Formularvalidierung mit normalem PHP schnell zu Spaguetti-Code wird.

e-satis
quelle
21
Sie haben genau das Gegenteil von dem getan, was er wollte ... Einfachheit.
TravisO
2

Dieser überprüft Arrays und Strings:

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

  return strlen(trim($val)) ? true : false;
}
Chris Clower
quelle
Nicht schlecht. Die Antwort von PHPst macht dasselbe, aber präziser.
Allain Lalonde
2

Um robuster zu sein (Tabellierung, Rückgabe…), definiere ich:

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

Quellen:

bcag2
quelle
1

Wenn Sie überprüfen möchten, ob für ein Feld ein Wert angegeben ist, kann dieses Feld a string, an arrayoder undifined sein. Das Folgende ist also genug

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

empty () hat früher dafür gearbeitet, aber das Verhalten von empty () hat sich mehrmals geändert. Wie immer sind die PHP-Dokumente immer die beste Quelle für genaues Verhalten, und die Kommentare auf diesen Seiten bieten normalerweise einen guten Verlauf der Änderungen im Laufe der Zeit. Wenn Sie nach fehlenden Objekteigenschaften suchen möchten, ist derzeit eine sehr defensive Methode:

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