PDO::FETCH_CLASS 不传递类名作为参数

Posted

技术标签:

【中文标题】PDO::FETCH_CLASS 不传递类名作为参数【英文标题】:PDO::FETCH_CLASS without passing class name as a parameter 【发布时间】:2015-09-08 13:20:55 【问题描述】:

我遇到了一段代码,其中调用 PDO::FETCH_CLASS 时没有将类的名称作为参数传递,如下所示:

  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;
  

现在,在官方documentation 中写道:

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

所以我不确定我是否完全理解它们的意思以及它是如何工作的。 假设我有一个记录的users

id:1 姓名:乔什 等等..

那么PDO::FETCH_CLASS 怎么知道类名是什么?我可以以FETCH_CLASS 从数据库中获取类名的方式将列添加到我的记录中吗?记录结构的例子将受到高度赞赏...thx

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

【问题讨论】:

我有一种奇怪的感觉,这是一个错字,他们的意思是“表名”——但我是基于零事实证据:) 其实它只是返回一个\stdClass实例,比如PDO::FETCH_OBJ 【参考方案1】:

对于 fetchAll 方法,如果未提供类名且未引发 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 组合。它实际上是一种非常强大的技术,可以让您跳过工厂方法中的样板开关。

【讨论】:

引用源代码的答案的无可争辩的证明......喜欢:)【参考方案2】:

    我不确定我完全理解它们的意思或它是如何工作的

    他们的意思是,而不是

    $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() 的第二个参数,如上面的第一个示例所示。

    我应该在我的记录中添加带有类名的列吗?

    嗯,确实,也可以这样做——这是对这个功能更有用的用途:它使每个结果对象的类都依赖于记录本身,这在某些情况下可能很有用(即在并非结果集中的所有记录都具有相同的“类型”——例如:也许有些记录应该实例化 Employee 对象,而其他记录应该实例化 Customer 对象)。

【讨论】:

这不是我的反对意见,但这个SELECT 'UserClass' 应该可能是标记` 或根本没有。可能是他们投反对票并闭嘴的原因。 'SELECT 'UserClass', users.* FROM users' 不是有效的 php,会产生致命错误。 您在描述 FETCH_CLASS 的可能用例时是正确的 || FETCH_CLASSTYPE fetch 组合,因此我 +1。 ) @eggyal 来自我的评论 #1 仍然适用。事实上,我什至赞成 ;-) @Fred-ii-:我将 PHP 字符串从单引号改为双引号 — 所以 'UserClass' 现在是 SQL 字符串文字,它应该是(而不是一些错误的 PHP 标识符,因为它是)。

以上是关于PDO::FETCH_CLASS 不传递类名作为参数的主要内容,如果未能解决你的问题,请参考以下文章

带有连接表的 PDO FETCH_CLASS

PDO将对象键值作为id获取并将id保留在对象中

PDO::FETCH_CLASSTYPE - 意外结果

java有参方法对象做参数

PDO 返回空属性名称

list作为实参传给函数