Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement __isset() magic method in PHP?

I'm trying to make functions like empty() and isset() work with data returned by methods.

What I have so far:

abstract class FooBase{

  public function __isset($name){
    $getter = 'get'.ucfirst($name);
    if(method_exists($this, $getter))
      return isset($this->$getter()); // not working :(
      // Fatal error: Can't use method return value in write context 
  }

  public function __get($name){
    $getter = 'get'.ucfirst($name);
    if(method_exists($this, $getter))
      return $this->$getter();
  }

  public function __set($name, $value){
    $setter = 'set'.ucfirst($name);
    if(method_exists($this, $setter))
      return $this->$setter($value);
  }

  public function __call($name, $arguments){
    $caller = 'call'.ucfirst($name);
    if(method_exists($this, $caller)) return $this->$caller($arguments);   
  }

}

the usage:

class Foo extends FooBase{
  private $my_stuff;

  public function getStuff(){
    return $this->my_stuff;
  }

  public function setStuff($stuff){
    $this->my_stuff = $stuff;
  }
}


$foo = new Foo();

if(empty($foo->stuff)) echo "empty() works! \n"; else "empty() doesn't work:( \n";
$foo->stuff = 'something';
if(empty($foo->stuff)) echo "empty() doesn't work:( \n"; else "empty() works! \n";

http://codepad.org/QuPNLYXP

How can I make it so empty/isset return true/false if:

  • my_stuff above is not set, or has a empty or zero value in case of empty()
  • the method doesn't exist (not sure if neeed, because I think you get a fatal error anyway)

?

like image 345
Alex Avatar asked Jun 05 '11 11:06

Alex


People also ask

What is magic methods in PHP with examples?

Magic methods in PHP are special methods that are aimed to perform certain tasks. These methods are named with double underscore (__) as prefix. All these function names are reserved and can't be used for any purpose other than associated magical functionality. Magical method in a class must be declared public.

What is __ method __ in PHP?

"Method" is basically just the name for a function within a class (or class function). Therefore __METHOD__ consists of the class name and the function name called ( dog::name ), while __FUNCTION__ only gives you the name of the function without any reference to the class it might be in.

Which magic method is used to implement overloading PHP?

In PHP function overloading is done with the help of magic function __call(). This function takes function name and arguments.


3 Answers

public function __isset($name){
    $getter = 'get'.ucfirst($name);
    return method_exists($this, $getter) && !is_null($this->$getter());
}

This check whether or not $getter() exists (if it does not exist, it's assumed that the property also does not exist) and returns a non-null value. So NULL will cause it to return false, as you would expect after reading the php manual for isset().

like image 116
Arjan Avatar answered Oct 02 '22 01:10

Arjan


A bit more option not to depend on getter

public function __isset($name)
{
    $getter = 'get' . ucfirst($name);
    if (method_exists($this, $getter)) {
        return !is_null($this->$getter());
    } else {
        return isset($this->$name);
    }
}
like image 45
Ansar Ahmed Avatar answered Oct 02 '22 01:10

Ansar Ahmed


Your code returns error because of these lines:

if(method_exists($this, $getter))
return isset($this->$getter());

You can just replace it with:

if (!method_exists($this), $getter) {
    return false; // method does not exist, assume no property
}
$getter_result = $this->$getter();
return isset($getter_result);

and it will return false if the getter is not defined or it returns NULL. I propose you should better think of the way you determine some property is set or not.

The above code is also assuming that you are creating getters for all of your properties, thus when there is no getter, the property is assumed as not set.

Also, why are you using getters? They seem to be some overkill here.

like image 33
Tadeck Avatar answered Oct 02 '22 01:10

Tadeck