Как реализовать магический метод 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

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

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

?

3 ответов


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

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


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

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

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

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. Я предлагаю вам лучше подумать о том, как вы определите некоторые свойства или нет.

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

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