简体   繁体   English

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

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

I was wondering how fetchAll of PDO is actually implemented to get an Idea how to map the result from the database including a GROUP_CONCAT() comma separated list string to an array property.我想知道如何实际实现 PDO 的 fetchAll 以了解如何从数据库中获取 map 的结果,包括 GROUP_CONCAT() 逗号分隔的列表字符串到数组属性。

Having a sql like有一个 sql 像

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

Will return something like会返回类似的东西

id (int)标识(整数) referencingNames (srting)引用名称 (srting)
1 1 Mark, Mona, Sam马克、莫娜、山姆
2 2 Jim, Tom, Sara, Mike吉姆、汤姆、萨拉、迈克
3 3 ... ...

My Object to map to looks like this我的 Object 到 map 看起来像这样

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

When I call my php code then:当我调用我的 php 代码时:

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

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

I am running into a type error, as referencingNames is obviously a string .我遇到了类型错误,因为referencingNames显然是一个string

What I then tried was to set $referencingNames private and use the magic function __set() as it says in the php docs the following然后我尝试将$referencingNames设置为私有并使用魔法 function __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;
    }
  } 
}

The bad news: this didn't work out.坏消息:这没有成功。 I get back an object where refNamesList stays null.我返回一个 object,其中 refNamesList 保持 null。 Logging the call of __set() did not give me any output, so I assume, it does not get called.记录__set()的调用并没有给我任何 output,所以我假设它没有被调用。

Has anybody an Idea how I can map GROUP_CONCAT to an array with PDOs fetchAll() without building my own solution?有没有人知道我如何在不构建自己的解决方案的情况下将 map GROUP_CONCAT放到带有 PDO fetchAll()的数组中? I mean, fetching all, and iterating the whole thing is still an option, but I was wondering if I can do this more elegantly anyhow.我的意思是,获取所有内容并迭代整个内容仍然是一种选择,但我想知道我是否可以更优雅地做到这一点。

As the name of the column you are loading is part of the class, it's setting that value anyway without having to call the __set method.由于您正在加载的列的名称是 class 的一部分,因此无论如何它都会设置该值,而无需调用__set方法。 So one way (seems to work) is to add a column alias which doesn't exist in the class - nameList in this example...因此,一种方法(似乎可行)是添加一个列别名,该别名在 class 中不存在 - 本示例中为 nameList ...

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

this should then call the __set method and you can process when you get nameList...这应该然后调用__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;
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM