10
votes

PDO FETCH_CLASS avec des tables jointes

Disons que j'ai 2 objets PHP: xxx

et xxx

Chaque poste a une contrainte unique avec 1 utilisateur dans la base de données .

Je veux remplir des données dans la méthode "Post" -Object avec PDOS "FETCH_CLASS" fonctionnant pour tous les attributs "Post", mais comment remplir les attributs de "utilisateur"?

Mon instruction SQL ressemble à ceci: xxx

merci!

Mise à jour: < P> ATM Je remplis mon "post" -Class comme ceci: xxx

alors comment devrais-je devoir changer cela pour remplir également l'autre classe "utilisateur"?

solution: xxx


1 commentaires

Votre question a aidé beaucoup! Merci!


5 Réponses :


2
votes

Il n'y a pas de soutien pour le Direcome en AOP aussi loin que je suis au courant. Typiquement, si vous devez créer un graphe d'objet complexe à partir du résultat de la requête, c'est la responsabilité d'un orj.

Si vous avez besoin de cette fonctionnalité, je me recommande d'utiliser doctrine ou propulser par opposition à écrire quelque chose vous-même. Il y en a d'autres aussi qui peut être un poids plus léger, mais je n'ai aucune expérience avec eux.

EDIT:

Je pense peut-être que j'ai mal compris la question bien sûr d'autres pourraient. Je pense que la vraie question était la suivante: comment accéder aux colonnes jointes, non cessiciellement comment créer un objet à partir d'eux.

Dans ce cas simplement en utilisant une méthode standard arry Fethc, comme PDO :: Fetch_assoc , pdo :: fetch_numérique ou pdo :: fetch_both vous donnera toutes les colonnes que vous avez interrogées.

Donc, si vous voulez tourner que dans un "graphique d'objet", vous devez le faire manuellement pas en utilisant PDO :: fetch_class .

par exemple: xxx


7 commentaires

Merci. ATM Je pense que j'aurais dû rester loin de PDO si c'est trop "complexe". Quelles applications existent même sans une simple jointure?


Je ne comprends pas ce qui est si complexe à ce sujet, en particulier envisager la seule autre option est mysqli qui est plus difficile à travailler avec et plus de Verbose. Ni le soutien de la "hydratation" une relation complexe d'un résultat de requête jointe.


Je ne sais pas si je comprends votre commentaire correctement. Êtes-vous d'accord pour dire que PDO devrait soutenir cela? Est-ce que cela le supporte quand ne pas utiliser fetch_class? Je vais regarder ça maintenant ...


Si vous avez utilisé fetch_assoc ou fetch_numérique Il vous donnera toutes les colonnes de la requête ... Je pensais que vous demandiez spécifiquement comment créer plusieurs objets à partir d'un résultat de la requête jointe.


Je ne suis pas intentionnellement incertain mais je comprends qu'il ne suffit pas assez d'être plus précis;) Je n'essayais pas de lire avec ma requête "rejoignée" et remplir les deux objets, pouvez-vous m'aider à y arriver?


Enfin, l'a fait grâce à vous. Je vais ajouter la solution ci-dessus. MERCI!


@RAPHAEL JEGER Vous pouvez ajouter un champ / attribut post_author "à votre classe PHP Post. Et ensuite rejoindre les tables requises ensemble.



1
votes

Pas vraiment une réponse pour le QQ, mais parce que cela empêche Google (oui, je connais sa plus d'un an). Vous constaterez que cela est incroyablement plus rapide de passer des boucles et de interroger chaque table séparément.


    SELECT post.id, 
           post.text, 
           post.user_id, 
    FROM POST INNER JOIN User on post.user_id = user.id
      $statement = $db -> prepare($query);
        $statement -> execute();
        $statement -> setFetchMode(PDO::FETCH_CLASS, 'Post');
        $posts = $statement -> fetchAll();

    SELECT user.id, 
           user.name 
    FROM POST INNER JOIN User on post.user_id = user.id
      $statement = $db -> prepare($query);
        $statement -> execute();
        $statement -> setFetchMode(PDO::FETCH_CLASS, 'User');
        $users = $statement -> fetchAll();
    


0 commentaires

0
votes

Peut-être utiliser PDO :: FETCH_NAMED Si vous travaillez plusieurs tables. Ou utilisez PDO :: Attr_Fetch_Table_Names.


0 commentaires

1
votes

Vous pouvez essayer d'utiliser une méthode __set, comme ceci: xxx


1 commentaires

Cela ne signifie-t-il pas que post :: $ id sera toujours null ?



0
votes

Mon approche pour la solution:

function groupQueryJoinClasses(\PDOStatement $stmt, $joinInfo = [], $idProperty = 'id')
{
    $result = [];

    $records = $stmt->fetchAll();

    if ( !empty($joinInfo) ) {
        foreach ($records as $record) {
            if ( !isset($result[$record->$idProperty]) ) {
                $result[$record->$idProperty] = $record;
            }
            foreach ($joinInfo as $target => $classInfo) {
                $vars = get_object_vars($record);
                $class = new $classInfo['class']();
                foreach ($vars as $key => $value) {
                    $keyData = explode('.', $key);
                    if ( $keyData[0] == $classInfo['prefix']) {
                        $class->$keyData[1] = $value;
                        unset($result[$record->$idProperty]->$key);
                    }
                }
                if ( !is_array( $result[$record->$idProperty]->$target) ) {
                    $result[$record->$idProperty]->$target = [];
                }
                $targetArray = &$result[$record->$idProperty]->$target;
                $targetArray[] = $class;
            }
        }
    } else {
        $result = $records;
    }

    return $result;
}

function getModel($query, $data, $entryClass, $joinInfo, $idProperty = 'id') {
    $pdo = new PDO(...);
    $stmt = $pdo->prepare($query);
    $stmt->execute($data);

    $stmt->setFetchMode(\PDO::FETCH_CLASS, $entryClass);

    return groupQueryJoinClasses($stmt, $joinInfo , $idProperty);
}

// Sample request

$query =
    'SELECT
        u.id as "id",
        p.id as "Post.id",
        p.name as "Post.name"
    FROM `user` u
    LEFT JOIN `posts` p ON p.user_id = u.id
    where id = :id'
;
$data = [ ':id' => 1 ];

$joinInfo = [
    'posts' => [
        'class' => Post::class,
        'prefix'=> 'Post'
    ]
];
$flowRules = getModel($query, $data, User::class, $joinInfo);


0 commentaires