如何使用 pdo->fetchAll 和模式 PDO::FETCH_CLASS 从字符串映射 GROUP_CONCAT 到数组

How to map GROUP_CONCAT with pdo->fetchAll and mode PDO::FETCH_CLASS from string to an array

我想知道 PDO 的 fetchAll 实际上是如何实现的,以便获得如何将数据库中的结果(包括 GROUP_CONCAT() 逗号分隔列表字符串)映射到数组 属性 的想法。

有一个sql喜欢

$query = "Select a.id, GROUP_CONCAT(b.name) AS referencingNames FROM a JOIN b on (a.id = b.id_a)"

会不会return像

id (int) referencingNames (srting)
1 Mark, Mona, Sam
2 Jim, Tom, Sara, Mike
3 ...

我要映射到的对象如下所示

class someObject {
  public int $id;
  public array $referencingNames;
}

当我调用 php 代码时:

 $pdo = new PDO(....)
 $statement = $pdo->prepare($query);
 $statement->execute();

 $objects = $statement->fetchAll(PDO::FETCH_CLASS, someObject::class);

我 运行 遇到类型错误,因为 referencingNames 显然是 string.

然后我尝试将 $referencingNames 设置为私有并使用魔法函数 __set(),如 php 文档中所述

is run when writing data to inaccessible (protected or private) or non-existing properties

class someObject {
  public int $id;
  private string $referencingNames;

  public ?array $refNamesList;

  public function __set($name, $value) 
  {
    if($name == "referencingNames") {
        $this->referencingNames = $value;
        $this->refNamesList = explode(",", $value);
    } else {
        $this->$name = $value;
    }
  } 
}

坏消息:这没有成功。我取回了一个对象,其中 refNamesList 保持为空。记录 __set() 的调用没有给我任何输出,所以我假设它没有被调用。

有人知道如何在不构建自己的解决方案的情况下将 GROUP_CONCAT 映射到具有 PDO fetchAll() 的数组吗? 我的意思是,获取所有内容并迭代整个内容仍然是一种选择,但我想知道无论如何我是否可以更优雅地做到这一点。

由于您要加载的列的名称是 class 的一部分,因此无论如何都会设置该值,而不必调用 __set 方法。因此,一种方法(似乎可行)是添加一个列别名,该别名在 class - nameList 中不存在,在此示例中...

$query = "Select a.id, GROUP_CONCAT(b.name) AS nameList 
             FROM a 
             JOIN b on (a.id = b.id_a)"

这应该会调用 __set 方法,您可以在获取 nameList 时进行处理...

class someObject {
  public int $id;
  public array $referencingNames;

  public function __set($name, $value)
  {
    if($name == "nameList") {
        $this->referencingNames = explode(",", $value);
    } else {
        $this->$name = $value;
    }
  }
}