Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Countable objects and empty

Tags:

php

count

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?

like image 461
GordonM Avatar asked May 25 '12 10:05

GordonM


2 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

like image 147
Andreas Wong Avatar answered Nov 16 '22 16:11

Andreas Wong


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.

like image 5
jtrumbull Avatar answered Nov 16 '22 14:11

jtrumbull