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

PHP PDO: выборка данных как объектов - свойств, назначенных ПЕРЕД вызовом __construct. Это верно?

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

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

Я больше работал с 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 - потому что все имена имеют "имя".

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

Update

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

Ответ 3

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

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

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

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