Как реализовать магический метод isset() в PHP?


Я пытаюсь заставить такие функции, как empty() и isset(), работать с данными, возвращаемыми методами.

Что у меня есть на данный момент:

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);   
  }

}

Использование:

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

Как я могу сделать так, чтобы он был пустым/возвращал значение true/false, если:

  • my_stuff выше не задано или имеет пустое или нулевое значение в случае empty()
  • метод не существует (не уверен, что это необходимо, потому что я думаю, что вы получаете фатальную ошибку в любом случае)

?

Author: Alex, 2011-06-05

3 answers

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

Это проверяет, существует ли $getter() (если оно не существует, предполагается, что свойство также не существует) и возвращает ненулевое значение. Поэтому NULL приведет к возвращению значения false, как и следовало ожидать после прочтения руководства по php для isset().

 7
Author: Arjan, 2011-06-05 12:02:53

Немного больше возможностей не зависеть от геттера

public function __isset($name)
{
    $getter = 'get' . ucfirst($name);
    if (method_exists($this, $getter)) {
        return !is_null($this->$getter());
    } else {
        return isset($this->$name);
    }
}
 3
Author: Ansar Ahmed, 2014-03-18 16:12:19

Ваш код возвращает ошибку из-за следующих строк:

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

Вы можете просто заменить его на:

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

И он вернет значение false, если получатель не определен или он возвращает NULL. Я предлагаю вам лучше подумать о том, как вы определяете, установлено какое-то свойство или нет.

Приведенный выше код также предполагает, что вы создаете геттеры для всех своих свойств, таким образом, когда геттера нет, свойство считается не установленным.

Кроме того, почему ты используя геттеры? Они кажутся здесь каким-то излишеством.

 1
Author: Tadeck, 2011-06-05 11:55:44