14

I have a "getter" method like

function getStuff($stuff){
  return 'something';
}

if I check it with empty($this->stuff), I always get FALSE, but I know $this->stuff returns data, because it works with echo.

and if I check it with !isset($this->stuff) I get the correct value and the condition is never executed...

here's the test code:

class FooBase{

  public function __get($name){
    $getter = 'get'.ucfirst($name);
    if(method_exists($this, $getter)) return $this->$getter();
    throw new Exception("Property {$getter} is not defined.");
  }
}

class Foo extends FooBase{
  private $my_stuff;

  public function getStuff(){
    if(!$this->my_stuff) $this->my_stuff = 'whatever';
    return $this->my_stuff;
  }

}

$foo = new Foo();
echo $foo->stuff;

if(empty($foo->stuff)) echo 'but its not empty:(';
if($foo->stuff) echo 'see?';
Alex
  • 66,732
  • 177
  • 439
  • 641

3 Answers3

27

empty() will call __isset() first, and only if it returns true will it call __get().

Implement __isset() and make it return true for every magic property that you support.

function __isset($name)
{
    $getter = 'get' . ucfirst($name);
    return method_exists($this, $getter);
}
Josh Davis
  • 28,400
  • 5
  • 52
  • 67
  • like this? `public function __isset($name){ $getter = 'get'.ucfirst($name); if(method_exists($this, $getter)) return true; }` – Alex Jun 05 '11 at 05:29
  • Judging from your example, yes, it seems it's the right way. I've updated my answer with a shorter version of the code. – Josh Davis Jun 05 '11 at 09:58
4

Magic getters are not called when checking with empty. The value really does not exist, so empty returns true. You will need to implement __isset as well to make that work correctly.

__isset() is triggered by calling isset() or empty() on inaccessible properties.

http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members

Community
  • 1
  • 1
deceze
  • 510,633
  • 85
  • 743
  • 889
  • I think it's a right answer. Also `empty` on functions gives us error, so formally current php behaviour has a bug, as it allows to calls empty on functions (even they are magic). Hmm... but they are magic. So, let it be not bug, but a feature. – gaRex Jun 05 '11 at 06:14
0

PHP's magic get method is named __get(). $this->stuff will not call getStuff(). Try this:

public function __get($property) {
    if ($property == 'stuff') {
        return $this->getStuff();
    }
}
David Harkness
  • 35,992
  • 10
  • 112
  • 134
  • but I have that. I made a class with with two __get and __set functions that call my methods, and extended it.. And it works with `isset()` but not with `empty()` :( – Alex Jun 05 '11 at 04:50
  • 1
    Yes, posting the *actual* code that you're using is generally preferable to some example code that doesn't really do what you're *actually* doing. :) – David Harkness Jun 05 '11 at 08:25