Lepszy sposób na sprawdzenie zmiennej pod kątem wartości null lub pustego ciągu?

174

Skoro PHP jest językiem dynamicznym, jaki jest najlepszy sposób sprawdzenia, czy podane pole jest puste?

Chcę się upewnić, że:

  1. null jest uważane za pusty ciąg
  2. ciąg zawierający tylko białe znaki jest uważany za pusty
  3. to „0” nie jest uważane za puste

Oto, co mam do tej pory:

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

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

Musi być na to prostszy sposób?

Allain Lalonde
źródło
1
Powiedziałbym, aby użyć pustego ($ question), ale to również uważa, że ​​0 jest puste.
Powerlord
2
warunki yoda są
okropne

Odpowiedzi:

278
// Function for basic field validation (present and neither empty nor only white space
function IsNullOrEmptyString($str){
    return (!isset($str) || trim($str) === '');
}
Michael Haren
źródło
7
Chociaż to rozwiązuje problem, nie jestem pewien, czy jest to prostsze. W każdym razie +1
Allain Lalonde,
4
Ponieważ OP prosi o „prostszą” wersję niezwykle prostej operacji, powiem, że „lepsze” jest tym, co jest faktycznie uzasadnione.
chaos
2
Zamieniłem to w funkcję. to powinno uprościć kod weryfikacyjny
Michael Haren,
7
jaki jest cel! isset () tutaj? czym się różni od is_null ()?
nickf
2
również return (! empty ($ question) || trim ($ question) === '');
SpYk3HH
109

Stary post, ale ktoś może go potrzebować tak jak ja;)

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

Zastąp $strswoją zmienną. NULLi ""oba zwracają 0 podczas używania strlen.

jrowe
źródło
4
I jest zawsze:if(strcmp('', $var) == 0)...
Piotr
12
Dlaczego == 0, a nie tylko jeśli (strlen ($ str))?
Noumenon
14
@Noumenon Ponieważ to pogorszyłoby czytelność bez rozwiązania czegokolwiek. Bardzo łatwo jest odczytać swoją sugestię jako „jeśli jest długość”, podczas gdy (oczywiście) oznacza odwrotnie.
Mattias Åslund,
11
Nie pomoże tylko na struny ze spacjami, jeśli komuś na to zależy
airboss
5
Jeśli zmienna nie jest ustawiona, spowoduje to ostrzeżenie
Konstantin Pereiaslov
25

Użyj funkcji empty () PHP. Następujące rzeczy są uważane za puste

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

Aby uzyskać więcej informacji, sprawdź pustą funkcję

kta
źródło
7
Plakat powiedział, że NIE chcą uważać, aby „0” było puste
dougd_in_nc
18

Pokornie zaakceptuję, jeśli się mylę, ale przetestowałem na własnym końcu i stwierdziłem, że poniższe działa do testowania zarówno zmiennych o wartości string (0) "", jak i NULL:

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

Które można również odwrócić, aby przetestować sukces jako taki:

if ( !$question ) {
  // Handle error here
}
Adal
źródło
czy mogę zasugerować „if (trim ($ n)) ..” w przeciwnym razie, jeśli zmienna $ _POST (na przykład) jest po prostu „”, zostanie uznana za prawidłową, podczas gdy w większości przypadków jest to tak dobre, jak pusty ciąg
StartupGuy
Jeśli „” nie jest akceptowalną wartością dla określonej funkcji, użycie przycinania byłoby świetnym pomysłem.
Adal
3
Zwróci to fałsz dla „0”, numeryczne 0 lub 0,0 i FALSE.
Vedmant
7

Uważaj na fałszywe negatywy trim()funkcji - wykonuje rzutowanie na łańcuch przed przycięciem, a zatem zwróci np. „Array”, jeśli przekażesz jej pustą tablicę. Może to nie stanowić problemu, w zależności od sposobu przetwarzania danych, ale z podanym kodem pole o nazwie question[]może zostać podane w danych POST i wyglądać na niepuste ciągi. Zamiast tego proponuję:

$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
źródło
Powiedziałbym, że jeśli otrzymasz tablicę, w której spodziewałeś się łańcucha, powinien to być błąd. Jeśli oczekujesz tablicy, powinieneś mieć do tego oddzielną funkcję filtrującą.
OIS,
Czy ten kod nie traktuje tego jako błąd? Jeśli filtrowanie odbywa się gdzie indziej, należy uważać, aby nie powielać wiedzy o regułach walidacji argumentów w oddzielnych miejscach.
grantwparks
3

Nie ma lepszego sposobu, ale ponieważ jest to operacja, którą zwykle wykonujesz dość często, lepiej zautomatyzuj proces.

Większość frameworków oferuje sposób, aby analizowanie argumentów było łatwym zadaniem. Możesz w tym celu zbudować własny obiekt. Szybki i brudny przykład:

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 masowo używa tego rodzaju cukru.

Ale mówisz o czymś więcej, ze swoim „// Błąd obsługi tutaj”. Mieszasz 2 zadania: pobieranie danych i ich przetwarzanie. To wcale nie jest to samo.

Istnieją inne mechanizmy, których możesz użyć do weryfikacji danych. Ponownie frameworki mogą pokazać najlepsze praktyki.

Utwórz obiekty reprezentujące dane formularza, a następnie dołącz procesy i powróć do niego. Wydaje się to o wiele bardziej pracochłonne niż hakowanie szybkiego skryptu PHP (i jest to pierwszy raz), ale jest on wielokrotnego użytku, elastyczny i znacznie mniej podatny na błędy, ponieważ sprawdzanie poprawności formularzy za pomocą zwykłego PHP ma tendencję do szybkiego przekształcania się w kod spaguetti.

e-satis
źródło
22
Zrobiłeś dokładnie odwrotne do tego, czego chciał ... prostota.
TravisO,
2

Ten sprawdza tablice i ciągi:

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

  return strlen(trim($val)) ? true : false;
}
Chris Clower
źródło
Nie jest zły. Odpowiedź PHPst robi to samo, ale jest bardziej zwięzła.
Allain Lalonde
2

aby być bardziej solidnym (tabulacja, powrót…), definiuję:

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

źródła:

bcag2
źródło
1

Jeśli chcesz sprawdzić, czy pole ma wartość, może to być a string, an arraylub nieokreślone. Tak więc wystarczy

function isSet($param)
{
    return (is_array($param) && count($param)) || trim($param) !== '';
}
PHPst
źródło
0

Empty () kiedyś działało w tym celu, ale zachowanie empty () zmieniło się kilka razy. Jak zawsze, dokumenty php są zawsze najlepszym źródłem dokładnego zachowania, a komentarze na tych stronach zwykle zawierają dobrą historię zmian w czasie. Jeśli chcesz sprawdzić brak właściwości obiektu, w tej chwili bardzo obronną metodą jest:

if (is_object($theObject) && (count(get_object_vars($theObject)) > 0)) {
NJInamdar
źródło