Tableau associatif et jointure

Eléphanteau du PHP | 35 Messages

20 mars 2014, 21:03

Bonjour à tous,

J'ai recherché des solutions à mon "problème" mais je n'ai pas trouvé de réponse (d'ailleurs, je ne sais pas trop quoi chercher car c'est davantage une question d'optimisation).

Je travaille actuellement sur l'espace d'administration d'un site ecommerce permettant de gérer les commandes faites sur le site.
Donc je dois récupérer les commandes, ainsi que les produits associés (je simplifie car le reste n'est pas important). Le problème, c'est que si je fais un simple JOIN (ou INNER JOIN), je me retrouve avec ce type de tableau:
array(
'1' => array(informations produit 1 de la commande numéro 1),
'1' => array(informations produit 2 de la commande numéro 1),
'2' => array(informations produit 1 de la commande numéro 2),
etc.
);

Donc derrière, je suis obligé de refaire une boucle sur ce tableau pour traiter les données et obtenir mon tableau comme je le souhaite pour l'afficher dans la vue.
Le tableau que j'ai à la fin (une fois les données reformatée) est celui-ci :
array(
'1' => array(
'id_produit_1' => informations produit 1 de la commande numéro 1,
'id_produit_2' => informations produit 2 de la commande numéro 1,
),
'2' => array(
'id_produit_1' => informations produit 1 de la commande numéro 2,
),
etc.
);

Ce qui me permet, dans ma vue, d'itérer sur le numéro de la commande et d'afficher les produits correspondants. Savez-vous si cela est faisable en SQL directement ?

Merci d'avance :)))

Franck

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

23 mars 2014, 16:43

salut,

non tu as une seule dimension (l'équivalent du tableau c’est le curseur est c'est déjà ce que tu as pour ton résultat et un curseur multidimensionnel cela n'existe pas ;) ).

tu peux très bien le faire dès le traitement de la requête initiale, soit en organisant une césure correctement, si tu est sur de l'ordre en gérant l'index de la liste finale.

par exemple
<?php

class Produit{
    private $nom;
    private $code;
    private $description;

    function __construct() {
    }

    /**
     * @param mixed $code
     */
    public function setCode($code) {
        $this->code = $code;
    }

    /**
     * @return mixed
     */
    public function getCode() {
        return $this->code;
    }

    /**
     * @param mixed $description
     */
    public function setDescription($description) {
        $this->description = $description;
    }

    /**
     * @return mixed
     */
    public function getDescription() {
        return $this->description;
    }

    /**
     * @param mixed $nom
     */
    public function setNom($nom) {
        $this->nom = $nom;
    }

    /**
     * @return mixed
     */
    public function getNom() {
        return $this->nom;
    }
}

class Commande{
    private $numero;
    private $date;
    private $client;
    private $listProduit;

    function __construct() {
    }

    /**
     * @param mixed $client
     */
    public function setClient($client) {
        $this->client = $client;
    }

    /**
     * @return mixed
     */
    public function getClient() {
        return $this->client;
    }

    /**
     * @param mixed $date
     */
    public function setDate($date) {
        $this->date = $date;
    }

    /**
     * @return mixed
     */
    public function getDate() {
        return $this->date;
    }

    /**
     * @param mixed $listProduit
     */
    public function setListProduit($listProduit) {
        $this->listProduit = $listProduit;
    }

    /**
     * @return mixed
     */
    public function getListProduit() {
        return $this->listProduit;
    }

    /**
     * @param mixed $numero
     */
    public function setNumero($numero) {
        $this->numero = $numero;
    }

    /**
     * @return mixed
     */
    public function getNumero() {
        return $this->numero;
    }

    public function addProduct(Produit $produit){
        $this->listProduit[] = $produit;
    }
}

// select des données
$commandes = [];
$oldCmd = new Commande();
// suivant ton sgbd *fetch* a toi de voir ;)
while($data = fetch()){
    if($data['numCommande'] != $oldCmd->getNumero()){
        $commandes[] = $oldCmd;
        $oldCmd = new Commande();
        $oldCmd->setNumero($data['numCommande']);
        // etc pour le reste
    }
    $p = new Produit();
    $p->setCode($data['codeproduit']);
    // etc
    $oldCmd->addProduct($p);
}
exemple poo parce que je trouve cela plus parlant mais le résultat est le même.

une autre solutions est possible : faire n +1 requête (où n est le nombre de commande). cela fera beaucoup plus de requête mais avec moins de données a chaque fois et plus ciblée.
Coté performance je ne sais pas lequel est la mieux un test serait intéressant.
tu peux aussi imaginer un système de cache pour ne pas aller rechercher des produits déjà utilisés (idem pour les infos clients) etc.

pour rester sur ce que tu as déjà la première solution me semble la mieux.

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 35 Messages

23 mars 2014, 23:40

Excellent, je n'avais pas penser à faire des classes et des instances de commandes et produit :))

Je vais tenter ça je crois car j'extrais énormément de données de la base donc ça commencer à être une usine à gaz donc des classes permettrait de structurer tout ça et d'avoir quelque chose de bien clean.

Merci encore !