如何使用 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;
}
}
}
我想知道 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;
}
}
}