Как реализовать магический метод 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";
Как я могу сделать так, чтобы он был пустым/возвращал значение true/false, если:
-
my_stuff
выше не задано или имеет пустое или нулевое значение в случаеempty()
- метод не существует (не уверен, что это необходимо, потому что я думаю, что вы получаете фатальную ошибку в любом случае)
?
3 answers
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
. Я предлагаю вам лучше подумать о том, как вы определяете, установлено какое-то свойство или нет.
Приведенный выше код также предполагает, что вы создаете геттеры для всех своих свойств, таким образом, когда геттера нет, свойство считается не установленным.
Кроме того, почему ты используя геттеры? Они кажутся здесь каким-то излишеством.