完整的问题应该是“这是正确的还是我不能指望的一些错误?”
为什么这是正确的行为?
我一直在使用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之前正在分配属性 - 因为名称都附加了“是名称”。
这是一些错误(在这种情况下我不能/不会指望它)或这是它应该的方式。因为它目前的工作方式真的很不错。
显然,according to one of the maintainers这不是一个错误。有人在2008年将其发布为一个错误,回复是“它不是一个错误,请阅读文档”。
但是,我真的很想知道为什么这是正确的行为。
答案 0 :(得分:12)
经过深入阅读后,我想我终于找到了答案:它有意识地以这种方式工作,你可以选择让它以其他方式运作。
有一个名为PDO::FETCH_PROPS_LATE
的大多数未记录的PDO常量,您可以使用它来使属性在构造后被提取到对象中。例如:
$obj = $STH->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'person');
将导致在创建对象后分配属性,因此上面的示例根本不会修改属性。当然,离开PDO::FETCH_PROPS_LATE
会导致它按照原始问题中我的示例中的描述进行操作。
维护人员似乎已经积极考虑这两种行为都是可取的,并且您可以选择这两种行为。文档甚至没有解释它 - 我reading through a list of PDO constants并且看到了它,然后给了它一个镜头。
答案 1 :(得分:3)
原因是,当您将对象序列化为数据库或字符串时,您(通常)不希望在反序列化时重新初始化属性。
答案 2 :(得分:2)
尝试使用PDO :: FETCH_INTO而不是PDO :: FETCH_CLASS。 From the docs:
PDO :: FETCH_INTO:更新所请求类的现有实例,将结果集的列映射到类中的命名属性
因此,您首先创建实例,然后将实例传递给您想要的获取方法。
话虽如此,是的,在调用__construct之前让FETCH_CLASS填充是相当违反直觉的。邮件列表上给出的答案是标准的复制粘贴“RTM”答案。如果FETCH_INTO有效,您应该使用建议的增强功能打开文档错误。