PDO :: FETCH_CLASS没有将类名作为参数传递

时间:2015-09-08 13:20:55

标签: php mysql pdo

我遇到了一段代码,其中调用了 function getUsers() { $DBH = $this->getDbh(); $query = "SELECT * FROM users"; try { $STH = $DBH->query($query); $users = $STH->fetchAll(PDO::FETCH_CLASS); } catch(PDOException $e) { } return $users; } 而没有将类的名称作为参数传递,如下所示:

users

现在,在官方documentation中它说:

  

如果fetch_style包含PDO :: FETCH_CLASSTYPE(例如PDO :: FETCH_CLASS | PDO :: FETCH_CLASSTYPE),则类的名称由第一列的值确定。

所以我不确定我究竟是什么意思,也不知道它是如何运作的。 假设我有一个记录的PDO::FETCH_CLASS

  • ID:1
  • 名:约什
  • 等......

那么FETCH_CLASS如何知道班级名称是什么?我可以使用类名称将列添加到我的记录中<%= f.collection_select :order_type, Order::TYPES , :to_s, :to_s, {include_blank: false}%>将从数据库中获取类名吗?记录结构的例子将受到高度赞赏... thx

*我正在测试这个类但不是作者,所以更改类是无关紧要的

2 个答案:

答案 0 :(得分:5)

对于 fetchAll 方法,如果未提供classname且未引发PDO::FETCH_CLASSTYPE标志,则返回stdClass对象(与PDO::FETCH_OBJ一样)。这就是发生的事情(lxr):

1436    switch(how & ~PDO_FETCH_FLAGS) {
1437    case PDO_FETCH_CLASS:
1438        switch(ZEND_NUM_ARGS()) {
1439        case 0:
1440        case 1:
1441            stmt->fetch.cls.ce = zend_standard_class_def;
1442            break

然后,在do_fetch中,由于没有提供类名,因此该值保持不变。这是有道理的,因为stdClass有时被认为是一种匿名类。 )

这解释了你必须处理的代码; @ eggyal的回答解释了如何使用PDO::FETCH_CLASS || PDO::FETCH_CLASSTYPE组合。它实际上是一种非常强大的技术,允许您跳过工厂方法中的样板开关。

答案 1 :(得分:2)

  1.   

    我不确定我究竟是什么意思,也不知道它是如何运作的

    他们的意思是代替

    $STH = $DBH->query("SELECT * FROM users");
    $users = $STH->fetchAll(PDO::FETCH_CLASS, 'UserClass');
    

    可以执行以下操作:

    $STH = $DBH->query("SELECT 'UserClass', users.* FROM users");
    $users = $STH->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
    

    但是,这不是特别有用:为什么要将类名硬编码到SQL中,只让MySQL将其与每条记录一起返回,并且PDO在实例化结果对象时解析每个字段(即每条记录)?最好只是将类名指定为fetchAll()的第二个参数,如上面第一个例子所示。

  2.   

    我应该使用类名添加列到我的记录吗?

    实际上,人们也可以这样做 - 这是对这个功能的一个更有用的用法:它使每个结果对象的类依赖于记录本身,这在某些情况下可能是有用的(即并非结果集中的所有记录都具有相同的“类型” - 例如:可能某些记录应实例化Employee个对象,而其他记录则应实例化Customer个对象。