PHP PDO: выборка данных как объектов - вызывается свойство, присвоенное ПЕРЕД __construct. Это правильно? - PullRequest
11 голосов
/ 19 мая 2010

Полный вопрос должен быть «Это правильно или это какая-то ошибка, на которую я не могу рассчитывать?»

ПОЧЕМУ это правильное поведение?

Я больше работаю с PDO и, в частности, играю с извлечением данных непосредственно в объекты. При этом я обнаружил это:

Если я получу данные непосредственно в объект, подобный этому:

$STH = $DBH->prepare('SELECT first_name, address from people WHERE 1');
$obj = $STH->fetchAll(PDO::FETCH_CLASS, 'person');

и иметь такой объект:

class person {
  public $first_name;
  public $address;

  function __construct() {
    $this->first_name = $this->first_name . " is the name";
  }
}

Это показывает, что свойства присваиваются до вызова __construct - потому что к именам добавлено «имя».

Это какая-то ошибка (в этом случае я не могу / не буду рассчитывать на это) или это так, как и должно быть. Потому что это действительно неплохо, так как работает сейчас.

Обновление

По-видимому, по словам одного из сопровождающих , это не ошибка. Кто-то опубликовал сообщение об ошибке в 2008 году, на что он ответил: «Это не ошибка, прочтите документы».

Однако мне бы очень хотелось узнать, ПОЧЕМУ это правильное поведение.

Ответы [ 3 ]

12 голосов
/ 19 мая 2010

После долгого прочтения, я, наконец, нашел ответ: он намеренно работает таким образом, и у вас есть возможность заставить его работать иначе.

Существует в основном недокументированная константа PDO, называемая PDO::FETCH_PROPS_LATE, которую вы можете использовать, чтобы заставить свойства извлекаться в объект после его создания. Например:

$obj = $STH->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'person');

Будет вызывать назначение свойств ПОСЛЕ создания объекта, поэтому мой пример выше не будет изменять свойства вообще. Отключение PDO::FETCH_PROPS_LATE, конечно, заставляет его действовать так, как описано в моем примере в исходном вопросе.

Сопровождающие, похоже, активно считали, что оба поведения могут быть желательны, и дали вам возможность сделать и то и другое. Документация даже не объясняет этого - я читал список констант PDO , видел и проверял.

3 голосов
/ 24 сентября 2012

Причина в том, что при сериализации объекта, либо в базу данных, либо в строку, вы (обычно) не хотите повторно инициализировать свойства при десериализации его.

2 голосов
/ 19 мая 2010

Попробуйте использовать PDO :: FETCH_INTO вместо PDO :: FETCH_CLASS. Из документов:

PDO :: FETCH_INTO: обновляет существующий экземпляр запрошенного класса, сопоставляя столбцы результирующего набора с именованными свойствами в классе

Итак, вы сначала должны создать экземпляр, а затем передать экземпляр нужному методу извлечения.

Как говорится, да, довольно нелогично, чтобы FETCH_CLASS заполнял перед вызовом __construct. Ответ, приведенный в списке рассылки, является стандартным ответом «RTM». Если FETCH_INTO работает, вы должны открыть ошибку документации с предлагаемыми улучшениями.

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