Подтвердить что ты не робот

PHP empty() для __get accessor

Использование PHP 5.3 Я испытываю странное/неинтуитивное поведение при применении empty() к динамическим свойствам объекта, полученным с помощью функции перегрузки __get(). Рассмотрим следующий фрагмент кода:

<?php

class Test {

  protected $_data= array(
   'id'=> 23,
   'name'=> 'my string'
  );

  function __get($k) {
    return $this->_data[$k];
  }

}

$test= new Test();
var_dump("Accessing directly:");
var_dump($test->name);
var_dump($test->id);
var_dump(empty($test->name));
var_dump(empty($test->id));

var_dump("Accessing after variable assignment:");
$name= $test->name;
$id= $test->id;
var_dump($name);
var_dump($id);
var_dump(empty($name));
var_dump(empty($id));

?>

Выход этой функции следующий. Сравните результаты проверок empty() на первом и втором наборах результатов:

Установить # 1, неожиданный результат:

string(19) "Accessing directly:"
string(9) "my string"
int(23)
bool(true)
bool(true)

Ожидайте, что Set # 1 вернется так же, как Set # 2:

string(36) "Accessing after variable assignment:"
string(9) "my string"
int(23)
bool(false)
bool(false)

Это действительно непонятно и неинтуитивно. В свойствах объекта выводятся непустые строки, но empty() считает их пустыми. Что здесь происходит?

4b9b3361

Ответ 1

Основываясь на чтении справочной страницы empty и комментариев (Ctrl-F для isset и/или двойных подчеркиваний), она выглядит например, это известное поведение, и если вы хотите, чтобы ваши методы __set и __get и empty играли хорошо вместе, существует неявное предположение, что вы реализуете магический метод __isset.

Это немного неинтуитивно и запутанно, но это имеет тенденцию происходить с большинством метапрограмм, особенно в такой системе, как PHP.

Ответ 2

В этом примере empty() вызывает функцию перегрузки __isset(), а не функцию перегрузки __get(). Попробуйте следующее:

class Test {

  protected $_data= array(
   'id'=> 23,
   'name'=> 'my string'
  );

  function __get($k) {
    return $this->_data[$k];
  }

  function __isset($k) {
    return isset($this->_data[$k]);
  }

}