124

How to find if an object is empty or not in PHP.

Following is the code in which $obj is holding XML data. How can I check if it's empty or not?

My code:

$obj = simplexml_load_file($url);
FelipeAls
  • 21,711
  • 8
  • 54
  • 74
sandbox
  • 2,631
  • 9
  • 33
  • 39
  • possible duplicate of [PHP object holding XML data](http://stackoverflow.com/questions/9411681/php-object-holding-xml-data) – Pekka Feb 23 '12 at 11:28
  • possible duplicate of [How to check if object is empty in PHP?](http://stackoverflow.com/questions/1389431/how-to-check-if-object-is-empty-in-php) – kenorb Mar 04 '15 at 22:23

15 Answers15

153

You can cast to an array and then check if it is empty or not

$arr = (array)$obj;
if (!$arr) {
    // do stuff
}
Peter Kelly
  • 14,253
  • 6
  • 54
  • 63
  • 9
    The typecasting doesn't work for me, because I get the error: **PHP Parse error: syntax error, unexpected '(array)' (array) (T_ARRAY_CAST) in ...** I use PHP version 5.4.28 and the first option with two lines of code works for me. – Coanda May 18 '14 at 13:34
  • Had the same error when uploading a WordPress plugin, seems that they also use an older version of PHP. – Asaf Mar 19 '15 at 09:58
  • 4
    empty doesn't actually check if an array is empty, `empty($var)` equivalent to `(!isset($var) || !$var)`. You can replace your `empty($arr)`s with `!$arr` since `array() == FALSE` – Timothy Zorn Aug 20 '15 at 18:35
  • 3
    The reason `empty((array) $obj)` does not work in PHP 5.4+ has nothing to do with typecasting on one line. You get the error because `empty()` takes a reference to the variables passed to it, and it cannot get a reference when typecasting unless you first store that typecasted variable in another variable. It does this because of what I described in my previous comment. It's rather frustrating that this is the accepted answer since it can lead people to believe that `empty()` checks if an array is "empty" which is not true - that's just a side effect of what it actually does. – Timothy Zorn Oct 23 '16 at 23:58
  • Will it work in php 7+, Or is it the right way to fix it. – kantsverma Oct 26 '18 at 09:01
40

Edit: I didn't realize they wanted to specifically check if a SimpleXMLElement object is empty. I left the old answer below

Updated Answer (SimpleXMLElement):

For SimpleXMLElement:

If by empty you mean has no properties:

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

OR

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

If SimpleXMLElement is one level deep, and by empty you actually mean that it only has properties PHP considers falsey (or no properties):

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

If SimpleXMLElement is more than one level deep, you can start by converting it to a pure array:

$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
}


Old Answer (simple object):

If you want to check if a simple object (type stdClass) is completely empty (no keys/values), you can do the following:

// $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";
}

Source: http://php.net/manual/en/language.oop5.object-comparison.php

Edit: added example

$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
  • 3,022
  • 2
  • 20
  • 18
  • Doesn't work in PHP7.2: ``PHP Warning: Uncaught Error: Call to undefined method stdClass::count()`` – Juha Untinen May 15 '19 at 12:09
  • 2
    @juha-untinen The solution with `->count()` is specifically for instances of `SimpleXMLElement` and not for instances of `stdClass`. I believe all of this still works in PHP7.2. – Timothy Zorn May 15 '19 at 19:45
28

You can cast your object into an array, and test its count like so:

if(count((array)$obj)) {
   // doStuff
}
Mohamed23gharbi
  • 1,710
  • 23
  • 28
16

Imagine if the object is not empty and in a way quite big, why would you waste the resources to cast it to array or serialize it...

This is a very easy solution I use in JavaScript. Unlike the mentioned solution that casts an object to array and check if it is empty, or to encode it into JSON, this simple function is very efficient concerning used resources to perform a simple task.

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

    return TRUE;
}

The solution works in a very simple manner: It wont enter a foreach loop at all if the object is empty and it will return true. If it's not empty it will enter the foreach loop and return false right away, not passing through the whole set.

random_user_name
  • 25,694
  • 7
  • 76
  • 115
stamat
  • 1,832
  • 21
  • 26
11

Using empty() won't work as usual when using it on an object, because the __isset() overloading method will be called instead, if declared.

Therefore you can use count() (if the object is Countable).

Or by using get_object_vars(), e.g.

get_object_vars($obj) ? TRUE : FALSE;
kenorb
  • 155,785
  • 88
  • 678
  • 743
7

Another possible solution which doesn't need casting to 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
  • 14,466
  • 3
  • 49
  • 65
2

in PHP version 8

consider you want to access a property of an object, but you are not sure that the object itself is null or not and it could cause error. in this case you can use Nullsafe operator that introduced in php 8 as follow:

$country = $session?->user?->getAddress()?->country;
Ali_Hr
  • 4,017
  • 3
  • 27
  • 34
2

there's no unique safe way to check if an object is empty

php's count() first casts to array, but casting can produce an empty array, depends by how the object is implemented (extensions' objects are often affected by those issues)

in your case you have to use $obj->count();

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

(that is not php's count http://www.php.net/count )

1

If you cast anything in PHP as a (bool), it will tell you right away if the item is an object, primitive type or null. Use the following code:

$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
  • 1,874
  • 4
  • 20
  • 27
  • 1
    wrong. $x = new \stdClass(); var_dump((bool)$x); prints 'true'; In your case, simpleXml may return false in some cases – Quamis Mar 19 '15 at 17:23
  • Correct. new stdClass() is a valid object, that's why it's true. PHP manual says, simplexml_load_file(), "Returns an object of class SimpleXMLElement with properties containing the data held within the XML document, or FALSE on failure." So, if you cast (bool)simplexml_load_file(), it will be true (because the function returned an object) but false (because the function returned false). – roosevelt Mar 21 '15 at 04:55
1

Based on this answer from kenorb, here's another one-liner for objects with public vars:

if (!empty(get_object_vars($myObj))) { ... }

Edit: Thanks to @mickmackusa's comment below - below is a more succinct one-liner, since this converts the object to an associative array (of accessible properties), and an empty array is falsy in PHP.

if (get_object_vars($myObj)) { ... }

Edit 2: In the event that your object is not a true object, get_object_vars() may produce warnings or alerts. This checks that the var is an object before ensuring that it's populated:

if (is_object($myObj) && get_object_vars($myObj)) { ... }

Just to reiterate - this is for objects with public/accessible variables. Objects with static, private, or protected vars will render false, which may be unexpected. See https://www.php.net/manual/en/function.get-object-vars.php

C. Foust
  • 31
  • 3
  • 1
    `!empty()` is also checking the existence of the passed in argument -- which is unnecessary. The simper way of doing the same thing is `if (get_object_vars($myObj)) {` – mickmackusa Feb 18 '23 at 03:52
0

I was using a json_decode of a string in post request. None of the above worked for me, in the end I used this:

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

if(json_encode($post_vals->object) != '{}')
{
    // its not empty
}
Frank Conry
  • 2,694
  • 3
  • 29
  • 35
0

Simply check if object type is null or not.

if( $obj !== null )
{
     // DO YOUR WORK
}
0

count($the_object) > 0 this is working and can be use for array too

demented hedgehog
  • 7,007
  • 4
  • 42
  • 49
0

If an object is "empty" or not is a matter of definition, and because it depends on the nature of the object the class represents, it is for the class to define.

PHP itself regards every instance of a class as not empty.

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

// results in bool(false)

There cannot be a generic definition for an "empty" object. You might argue in the above example the result of empty() should be true, because the object does not represent any content. But how is PHP to know? Some objects are never meant to represent content (think factories for instance), others always represent a meaningful value (think new DateTime()).

In short, you will have to come up with your own criteria for a specific object, and test them accordingly, either from outside the object or from a self-written isEmpty() method in the object.

nem75
  • 358
  • 3
  • 9
-1
$array = array_filter($array);
if(!empty($array)) {
    echo "not empty";
}

or

if(count($array) > 0) {
    echo 'Error';
} else {
    echo 'No Error';
}
Jørgen R
  • 10,568
  • 7
  • 42
  • 59
Muhammad Tahir
  • 2,351
  • 29
  • 25
  • While this may answer the question it’s always a good idea to put some text in your answer to explain what you're doing. Read [how to write a good answer](http://stackoverflow.com/help/how-to-answer). – Jørgen R Apr 09 '15 at 12:35