Home » Php » php – Countable objects and empty

php – Countable objects and empty

Posted by: admin July 12, 2020 Leave a comment

Questions:

If you do empty() on an array with no elements in it, you get true. However, if you do empty() on a Countable object with a count of 0 then you get false. It seems to me a 0 count Countable should be considered empty. Am I missing something?

<?php

class Test implements Countable
{
    public $count = 0;

    public function count ()
    {
        return intval (abs ($this -> count));
    }
}

$test = new Test ();

var_dump (empty ($test));
var_dump (count ($test));

$test -> count = 10;

var_dump (empty ($test));
var_dump (count ($test));

I would have expected the first call to empty to return true, but it doesn’t.

Is there a reasonable reason for this to be the case, or is it a bug?

How to&Answers:

From the docs:

Returns FALSE if var has a non-empty and non-zero value.

The following things are considered to be empty:

* "" (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 $var; (a variable declared, but without a value in a class)

I think $test in your case is still considered an Object, which is not in the list of what empty would return as TRUE

Answer:

As stated above, empty() does not consider count($obj) == 0 to be “empty”. The reason this doesn’t doesn’t work as expected is because arrays do not implement Countable i.e.

array() instanceof Countable // false

Probably an obvious workaround, but figured I would post this here.

function is_empty ($val) {
  return empty($val) || ($val instanceof Countable && empty(count($val)));
}

Example:

class Object implements Countable {

  protected $attributes = array();

  // ...

  public function count () {
    return count($this->attributes);
  }

}

$obj = new Object();
is_empty($obj) // TRUE

I should note that this solution works in my case, because I would have already defined is_empty() for prettiness alongside the other is_* methods.