简体   繁体   English

PHP PDO fetchAll,PDO :: FETCH_CLASS和join

[英]PHP PDO fetchAll, PDO::FETCH_CLASS and joins

I have a problem in the following code: 我在以下代码中遇到问题:

$query = 'SELECT user.id as id, pet.name as name FROM user 
          LEFT JOIN pet on pet.user_id = user.id
          WHERE user.id = 15';

$result = $pdo->query($query); 

This code will produce something similar to this: 此代码将生成类似于此的内容:

***************
| id | name   |
***************
| 1  | Mikey  |
***************
| 1  | Stewie |
***************
| 1  | Jessy  |
***************

Now, I'd like to use PDO::FETCH_CLASS to get an object. 现在,我想使用PDO::FETCH_CLASS来获取一个对象。 However, this method, at least to me, works fine only with simple SELECT statements. 但是,至少对我来说,这种方法只适用于简单的SELECT语句。 When you have a join statement, then it will fetch everything in a single class. 当你有一个join语句时,它将获取一个类中的所有内容。 In other words: 换一种说法:

$user = $result->fetchAll(PDO::FETCH_CLASS, 'User');
echo $user->name; // this will print the pet name (which is weird)

Therefore, I'd like to have something similar: 因此,我想要有类似的东西:

$pets = $user->pets; // an array holding Pet Objects 
foreach ($pets as $pet)
   echo $pet->name . "-"; 

which will produce: 这将产生:

Mikey - Stewie - Jessy -

How can I achieve this? 我怎样才能做到这一点?

You can't rely on PDO to do the job for you. 您不能依靠PDO为您完成这项工作。 PDO has no way to know where the dataset columns come from and it obviously can't figure out where you want to dump the data. PDO无法知道数据集列的来源,显然无法确定要转储数据的位置。

The simplest answer is that you have to write your own code. 最简单的答案是你必须编写自己的代码。 Fetch rows as arrays and populate your classes with it as it's always been done ;-) 将行作为数组获取并使用它填充类,因为它始终是完成的;-)

The technique you describe is ORM ( Object-relational mapping ). 您描述的技术是ORM( 对象关系映射 )。 There're some third-party libraries that implement it, such as Doctrine or Propel . 有一些第三方库实现它,例如DoctrinePropel

I open sourced a very small function that will transform joined results into a hierarchy. 我开源了一个非常小的函数,它将联接的结果转换为层次结构。 This avoids using heavy ORMs if you just need this small feature. 如果您只需要这个小功能,这可以避免使用繁重的ORM。 https://github.com/afilina/nestedsql https://github.com/afilina/nestedsql

You'd give it a statement like this: 你会给它一个这样的声明:

SELECT album.id AS albums__id, photo.id AS albums__photos__id
FROM album
LEFT JOIN photo ON photo.album_id = album.id;

and it will produce something this: 它会产生这样的东西:

stdClass Object
(
    [albums] => Array
        (
            [1] => stdClass Object
                (
                    [id] => 1
                    [photos] => Array
                        (
                            [1] => stdClass Object
                                (
                                    [id] => 1
                                )
                        )
                )
        )
)

Optionally, you can replace stdClass by your own classes. (可选)您可以用自己的类替换stdClass。

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

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