Jak sprawdzić, czy obiekt jest pusty w PHP?

Odpowiedzi:

130

Możesz rzutować na tablicę, a następnie sprawdzić, czy jest pusta, czy nie

$arr = (array)$obj;
if (!$arr) {
    // do stuff
}
Peter Kelly
źródło
9
Rzutowanie nie działa dla mnie, ponieważ pojawia się błąd: Błąd analizy PHP : błąd składni, nieoczekiwany '(tablica)' (tablica) (T_ARRAY_CAST) w ... Używam PHP w wersji 5.4.28 i pierwszej opcji z dla mnie działają dwie linie kodu.
Coanda
Wystąpił ten sam błąd podczas przesyłania wtyczki WordPress, wygląda na to, że używają również starszej wersji PHP.
Asaf
4
empty w rzeczywistości nie sprawdza, czy tablica jest pusta, empty($var)odpowiednik (!isset($var) || !$var). Możesz zamienić swoje empty($arr)s na !$arrodarray() == FALSE
Timothy Zorn
2
Przyczyna empty((array) $obj)nie działa w PHP 5.4+ nie ma nic wspólnego z rzutowaniem w jednej linii. Otrzymujesz błąd, ponieważ empty()pobiera odwołanie do przekazanych do niego zmiennych i nie może uzyskać referencji podczas rzutowania typów, chyba że najpierw zapiszesz tę zmienną przypisaną do innej zmiennej. Robi to z powodu tego, co opisałem w moim poprzednim komentarzu. To dość frustrujące, że jest to akceptowana odpowiedź, ponieważ może prowadzić do wniosku, że empty()sprawdza, czy tablica jest „pusta”, co nie jest prawdą - to tylko efekt uboczny tego, co faktycznie robi.
Timothy Zorn
Czy zadziała w php 7+, czy jest to właściwy sposób, aby to naprawić.
kantsverma
32

Edycja : nie zdawałem sobie sprawy, że chcieli konkretnie sprawdzić, czy obiekt SimpleXMLElement jest pusty. Starą odpowiedź zostawiłem poniżej

Zaktualizowana odpowiedź (SimpleXMLElement) :

W przypadku SimpleXMLElement:

Jeśli przez puste masz na myśli brak właściwości:

$obj = simplexml_load_file($url);
if ( !$obj->count() )
{
    // no properties
}

LUB

$obj = simplexml_load_file($url);
if ( !(array)$obj )
{
    // empty array
}

Jeśli SimpleXMLElement jest głęboki na jeden poziom, a pusty oznacza, że ​​ma tylko właściwości, które PHP uważa za falsey (lub żadnych właściwości):

$obj = simplexml_load_file($url);
if ( !array_filter((array)$obj) )
{
    // all properties falsey or no properties at all
}

Jeśli SimpleXMLElement ma więcej niż jeden poziom głębokości, możesz zacząć od konwersji go na czystą tablicę:

$obj = simplexml_load_file($url);
// `json_decode(json_encode($obj), TRUE)` can be slow because
// you're converting to and from a JSON string.
// I don't know another simple way to do a deep conversion from object to array
$array = json_decode(json_encode($obj), TRUE);
if ( !array_filter($array) )
{
    // empty or all properties falsey
}


Stara odpowiedź (prosty obiekt) :

Jeśli chcesz sprawdzić, czy prosty obiekt (typ stdClass) jest całkowicie pusty (brak kluczy / wartości), możesz wykonać następujące czynności:

// $obj is type stdClass and we want to check if it's empty
if ( $obj == new stdClass() )
{
    echo "Object is empty"; // JSON: {}
}
else
{
    echo "Object has properties";
}

Źródło: http://php.net/manual/en/language.oop5.object-comparison.php

Edycja : dodany przykład

$one = new stdClass();
$two = (object)array();

var_dump($one == new stdClass()); // TRUE
var_dump($two == new stdClass()); // TRUE
var_dump($one == $two); // TRUE

$two->test = TRUE;
var_dump($two == new stdClass()); // FALSE
var_dump($one == $two); // FALSE

$two->test = FALSE;
var_dump($one == $two); // FALSE

$two->test = NULL;
var_dump($one == $two); // FALSE

$two->test = TRUE;
$one->test = TRUE;
var_dump($one == $two); // TRUE

unset($one->test, $two->test);
var_dump($one == $two); // TRUE
Timothy Zorn
źródło
Nie działa w PHP7.2:PHP Warning: Uncaught Error: Call to undefined method stdClass::count()
Juha Untinen
2
@ juha-untinen Rozwiązanie z ->count()jest przeznaczone specjalnie dla wystąpień, SimpleXMLElementa nie dla wystąpień stdClass. Uważam, że wszystko to nadal działa w PHP7.2.
Timothy Zorn
21

Możesz rzucić swój obiekt na tablicę i przetestować jego liczbę w następujący sposób:

if(count((array)$obj)) {
   // doStuff
}
Mohamed23gharbi
źródło
12

Wyobraź sobie, że jeśli obiekt nie jest pusty i dość duży, po co marnować zasoby na rzutowanie go na tablicę lub serializowanie ...

To bardzo proste rozwiązanie, którego używam w JavaScript. W przeciwieństwie do wspomnianego rozwiązania, które rzutuje obiekt na tablicę i sprawdza, czy jest pusty, lub aby zakodować go do JSON, ta prosta funkcja jest bardzo wydajna w odniesieniu do zasobów używanych do wykonania prostego zadania.

function emptyObj( $obj ) {
    foreach ( $obj AS $prop ) {
        return FALSE;
    }

    return TRUE;
}

Rozwiązanie działa w bardzo prosty sposób: w ogóle nie wejdzie w pętlę foreach, jeśli obiekt jest pusty i zwróci true. Jeśli nie jest pusty, wejdzie w foreachpętlę i falseod razu wróci , nie przechodząc przez cały zestaw.

stamat
źródło
8

Użycie empty()nie będzie działało normalnie podczas używania go na obiekcie, ponieważ __isset()zamiast tego zostanie wywołana metoda przeciążania, jeśli zostanie zadeklarowana.

Dlatego możesz użyć count()(jeśli obiekt jest policzalny ).

Lub używając get_object_vars()np

get_object_vars($obj) ? TRUE : FALSE;
kenorb
źródło
7

Inne możliwe rozwiązanie, które nie wymaga odlewania, aby array:

// test setup
class X { private $p = 1; } // private fields only => empty
$obj = new X;
// $obj->x = 1;


// test wrapped into a function
function object_empty( $obj ){
  foreach( $obj as $x ) return false;
  return true;
}


// inline test
$object_empty = true;
foreach( $obj as $object_empty ){ // value ignored ... 
  $object_empty = false; // ... because we set it false
  break;
}


// test    
var_dump( $object_empty, object_empty( $obj ) );
biziclop
źródło
2

nie ma unikalnego bezpiecznego sposobu sprawdzenia, czy obiekt jest pusty

php's count () najpierw rzuca do tablicy, ale rzutowanie może wytworzyć pustą tablicę, w zależności od tego, jak obiekt jest zaimplementowany (obiekty rozszerzeń są często dotknięte tymi problemami)

w twoim przypadku musisz użyć $ obj-> count ();

http://it.php.net/manual/en/simplexmlelement.count.php

(to nie jest liczba php http://www.php.net/count )


źródło
1

Jeśli rzucisz cokolwiek w PHP jako (bool), to od razu powie Ci, czy element jest obiektem, typem pierwotnym czy null. Użyj poniższego kodu:

$obj = simplexml_load_file($url);

if (!(bool)$obj) {
    print "This variable is null, 0 or empty";
} else {
    print "Variable is an object or a primitive type!";
}
roosevelt
źródło
1
źle. $ x = nowa \ stdClass (); var_dump ((bool) $ x); drukuje „prawda”; W twoim przypadku simpleXml może w niektórych przypadkach zwrócić false
Quamis
Poprawny. new stdClass () jest prawidłowym obiektem, dlatego jest prawdziwe. Podręcznik PHP mówi, simplexml_load_file (), "Zwraca obiekt klasy SimpleXMLElement z właściwościami zawierającymi dane przechowywane w dokumencie XML lub FALSE w przypadku błędu." Tak więc, jeśli rzucisz (bool) simplexml_load_file (), będzie to prawda (ponieważ funkcja zwróciła obiekt), ale fałszywa (ponieważ funkcja zwróciła fałsz).
roosevelt
0

To, czy obiekt jest „pusty”, czy nie, jest kwestią definicji, a ponieważ zależy to od charakteru obiektu reprezentowanego przez klasę, definiowanie należy do klasy.

Sam PHP uważa, że ​​każda instancja klasy nie jest pusta.

class Test { }
$t = new Test();
var_dump(empty($t));

// results in bool(false)

Nie może istnieć ogólna definicja „pustego” obiektu. W powyższym przykładzie można argumentować, że wynik empty()powinien być true, ponieważ obiekt nie reprezentuje żadnej treści. Ale skąd PHP ma wiedzieć? Niektóre obiekty nigdy nie mają reprezentować treści (na przykład pomyśl o fabrykach), inne zawsze reprezentują znaczącą wartość (myśl new DateTime()).

Krótko mówiąc, będziesz musiał wymyślić własne kryteria dla konkretnego obiektu i odpowiednio je przetestować, albo z zewnątrz obiektu, albo z własnej isEmpty()metody w obiekcie.

nem75
źródło
0
$array = array_filter($array);
if(!empty($array)) {
    echo "not empty";
}

lub

if(count($array) > 0) {
    echo 'Error';
} else {
    echo 'No Error';
}
Muhammad Tahir
źródło
Chociaż może to odpowiedzieć na pytanie, zawsze dobrze jest umieścić w odpowiedzi jakiś tekst, aby wyjaśnić, co robisz. Przeczytaj, jak napisać dobrą odpowiedź .
Jørgen R
-1

Używałem json_decode ciągu w żądaniu postu. Żadne z powyższych nie działało u mnie, w końcu skorzystałem z tego:

$post_vals = json_decode($_POST['stuff']);

if(json_encode($post_vals->object) != '{}')
{
    // its not empty
}
Frank Conry
źródło