Полный вопрос должен быть «Правильно это или это какая-то ошибка, на которую я не могу рассчитывать?»
ПОЧЕМУ это правильное поведение?
Я больше работал с 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 году, на который ответ был «не ошибкой, прочитайте документы».
Тем не менее, мне очень хотелось бы знать, ПОЧЕМУ это правильное поведение.
После долгих чтений я, наконец, наткнулся на ответ: он работает намеренно, и у вас есть возможность заставить его действовать иначе.
В основном недокументированная константа PDO, называемая PDO::FETCH_PROPS_LATE
которую вы можете использовать, чтобы заставить свойства быть загружены в объект после его создания. Например:
$obj = $STH->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'person');
Будет вызывать присвоение свойств ПОСЛЕ создания объекта, поэтому мой пример выше не изменит свойства вообще. PDO::FETCH_PROPS_LATE
выключение PDO::FETCH_PROPS_LATE
заставляет его действовать, как описано в моем примере в исходном вопросе.
Составители, похоже, активно считают, что оба поведения могут быть желательными и дают вам возможность сделать это. Документация даже не объясняет это – я читал список констант PDO и видел это, и дал ему шанс.
Причина в том, что когда вы сериализуете объект, либо в базу данных, либо в строку, вы не (обычно) хотите повторно инициализировать свойства при их неэтериализации.
Попробуйте использовать PDO :: FETCH_INTO вместо PDO :: FETCH_CLASS. Из документов:
PDO :: FETCH_INTO: обновляет существующий экземпляр запрашиваемого класса, сопоставляя столбцы набора результатов с именованными свойствами в классе
Итак, сначала создайте экземпляр, а затем передайте экземпляр желаемому методу выборки.
Это, как говорится, да, контр-интуитивно, чтобы FETCH_CLASS заполнялся перед вызовом __construct. Ответ, указанный в списке рассылки, является стандартным ответом «RTM» для копирования и вставки. Если FETCH_INTO работает, вы должны открыть ошибку документации с предлагаемыми улучшениями.