Как реализовать магический метод __isset () в PHP? - PullRequest
11 голосов
/ 05 июня 2011

Я пытаюсь заставить функции типа 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()
  • метод не существует (не уверен, что нужен, потому что я думаю, что вы все равно получаете фатальную ошибку)

Ответы [ 3 ]

8 голосов
/ 05 июня 2011
public function __isset($name){
    $getter = 'get'.ucfirst($name);
    return method_exists($this, $getter) && !is_null($this->$getter());
}

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

3 голосов
/ 18 марта 2014

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

public function __isset($name)
{
    $getter = 'get' . ucfirst($name);
    if (method_exists($this, $getter)) {
        return !is_null($this->$getter());
    } else {
        return isset($this->$name);
    }
}
1 голос
/ 05 июня 2011

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

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

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

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

...