PHP empty () на методе доступа __get - PullRequest
25 голосов
/ 12 января 2010

Использование 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() для первого и второго наборов результатов:

Set # 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() считает их пустыми строками. Что здесь происходит?

Ответы [ 2 ]

33 голосов
/ 12 января 2010

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

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

4 голосов
/ 12 января 2010

В этом примере 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]);
  }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...