Вопрос: 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 - потому что имена имеют «имя», добавленное.

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

Обновить

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

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


11


источник


Ответы:


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

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

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

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

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


12



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


3



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

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

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

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


2