En vue de faire un panier, caddie...comme vous voudrez :)

Komoz
Invité n'ayant pas de compte PHPfrance

20 juin 2007, 16:51

Bonjour,

Je suis noob et cherche à me lancer dans mon premier gros script (prière de ne pas rire lol) :

J'ai une page avec un formulaire qui demande :
- combien j'en veux ?
- de l'article référence tant !

Ceux sont deux champs de saisie dont les valeurs sont postées sur une page de traitement/affichage.

Je cherche à faire avec les sessions un array simple de la forme [ref] [qte] (je sais pas si un id est utile dans ce cas ca donnerait [id] [ref] [qte].

Comment faire ? Est-ce que cela peut suffire pour faire tourner un site ?
Pourquoi des fois, c'est plus complexe avec des tableaux dans les tableaux...

Pour le moment j'ai fait ca, mais ca marche pas des masses :?
<? if (!isset($_SESSION['panier'])){
$_SESSION['panier']['id']['qte'] = array();
array_push($_SESSION['panier']['id']['qte'],$_POST['id'],$_POST['qte']);
}
foreach($_SESSION['panier'] as $cle=>$valeur) { 
    echo $cle.' : '.$valeur.'<br>'; 
}
?>
Merci de votre éventuelle aide

Komoz

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

20 juin 2007, 17:13

Voici un exemple simple et dumment commenté:
<?php
//*************************************************************************************************************
// Programme d'affichage d'un panier de commande
//
// Objectifs :
//        1. Obtenir la source du panier (ensembles d'articles commandés)
//        2. Traiter l'Ajout, la modification des quantités et la suppression d'articles
//        3. Afficher son contenu dans une table HTML sous forme d'une facture. Pour ça il faut faire des calculs :
//            3.1. Calculer pour chaque article sa valeur = prix unitaire (pu) * quantité commandée (qté)
//            3.2. Calculer le total hors taxe (tht) = somme des valeurs des articles 
//            3.3. Calculer le montant de la TVA (taux = 19%) = total hors taxe * 19/100
//            3.4. Calculer le montant TTC (ttc) = total hors taxe (tht) + montant de la TVA (tva)
//
//**************************************************************************************************************

//Source du panier
//Le panier est un tableau (array) composé de plusieurs lignes qui sont elles mêmes composées de colonnes (array)
//Une ligne article dans le panier est un tableau (array) composé des colonnes suivantes :
//        * réf: est la référence de l'article commandé (c'est un index unique qui désigne un et un seul article)
//        * désignation: est le nom de l'article commandé
//        * pu: est le prix unitaire de l'article
//        * qte: est la quantité commandée
//
// Comme exemple, le panier suivant contient 3 articles commandés par un client :
$panier_initial = array (
    "1"=> array ("réf"=>1, "désignation"=>"Ecran LCD 19''", "pu"=>199.99, "qté"=>1),
    "2"=> array ("réf"=>2, "désignation"=>"Disque dur 160 Go", "pu"=>100.00, "qté"=>1),
    "3"=> array ("réf"=>3, "désignation"=>"Clé USB 1 Go", "pu"=>10.00, "qté"=>1)
);
//Les numéros de lignes du panier "1", "2" et "3" sont les réf des articles, 
//celà permet de retrouver rapidement une ligne d'article pour la modifier ou la supprimer,
//celà permet aussi d'éviter l'ajout d'un article qui existe déjà
//
//Le panier doit être mémorisé dans une session pour assurer son évolution,
//activer la mémoire de session
session_start();

//Dans cet exemple, on initialise le panier s'il est absent de la session et on le retire de la session pour recommencer l'exemple
if ($_GET["action"]=="Recommencer") unset($_SESSION["panier"]);

//Initialiser la variable de session "panier" (juste pour cet exemple simple pour ne pas avoir besoin 
//d'un catalogue de choix)
if ( ! isset($_SESSION["panier"]) ) $_SESSION["panier"] = $panier_initial;

//ATTENTION: Les 2 dernières lignes de code ainsi que le tableau $panier_initial ne font pas partie de la gestion réelle du panier, 
//elles servent  simplement pour faire tourner cette démo, il faut les retirer lors de l'integration du script à la phase finale

//Créer la variable de session $panier à partir de la mémoire de session
$panier = $_SESSION["panier"]; //quand ce programme bouclera, cette variable contiendra les données évolutives du panier

//Le panier sera traité par des action de type Ajout, Modification et suppression
//
//L'ajout: action provenant de la page catalogue d'article
if ($_GET["action"] == "Ajout") {
    $réf = $_GET["réf"];
    $désignation = $_GET["désignation"];
    $pu = $_GET["pu"];
    $qté = $_GET["qté"] + $panier["$ref"]["qté"]; //permet d'ajouter la nouvelle qté si l'article existe déjà
    $panier ["$réf"] = array( "réf"=>$réf, "désignation"=>$désignation, "pu"=>$pu, "qté"=>$qté  );
}

//Modification de la qté
if ($_GET["action"] == "Modifier") {
    $réf = $_GET["réf"];
    $qté = $_GET["qté"];
    $panier ["$réf"]["qté"] = $qté; //réf est l'index et $qté est la valeur modifiée
}

//Suppression
if ($_GET["action"] == "Supprimer") {
    $réf = $_GET["réf"];
    unset( $panier ["$réf"] ); //$réf est l'index de l'article à supprimer
}

//Après le traitement, mettre à jour la session
$_SESSION["panier"] = $panier;

//Affichage du panier sous forme de facture
echo "<h1>Votre panier</h1>";
if (count($panier)>0){
//Début du panier
    //Affichage de l'entête du tableau 
    echo "<table border='1'>
            <tr>
                <th>Désignation</th>
                <th>Prix</th>
                <th>Quantité</th>
                <th>Valeur</th>
            </tr>";
            
    //Affichage des lignes du panier
    //tht: Total hors taxe = somme des valeurs des articles du panier
    $tht = 0;
    foreach ($panier as $ligne) {    
            //Afficher une ligne du panier     
            //Chaque ligne est un formulaire qui permet de la modifier    
            //La réf de l'article est cachée
            //La désignation et le pu sont en lecture seule (affichés)
            //La qté est modifiable (zone de texte)
            echo "
                <form>
                <input type='hidden' name='réf' value='$ligne[réf]'>
                <tr>
                    <td>$ligne[désignation]</td>
                    <td align='right'>".number_format($ligne["pu"],2,"."," ")."</td>
                    <td><input type='text' name='qté' value='$ligne[qté]' style='text-align:right'></td>
                    <td align='right'>".number_format($ligne["pu"]*$ligne["qté"], 2, ".", " ")."</td>
                    <td><input type='submit' name='action' value='Modifier'>
                    <td><input type='submit' name='action' value='Supprimer'>
                </tr>
                </form>";
            //Calcul de la somme des valeurs ( tht )
            $tht += $ligne["pu"]*$ligne["qté"];
    }
    //Calcul de la TVA et du TTC         
    $tva = $tht * 0.19;
    $ttc = $tht + $tva;
    //Affichage du pied du tableau
    echo "<tr>
            <th colspan=3 align='right'>Total HT</th> <th align='right'>".number_format($tht,2,"."," ")."</th>
        </tr>
        <tr>
            <th colspan=3 align='right'>Tva (19%)</th> <th align='right'>".number_format($tva,2,"."," ")."</th>
        </tr>
        <tr>
            <th colspan=3 align='right'>TTC</th> <th align='right'>".number_format($ttc,2,"."," ")." €</th>
        </tr>
        </table>";
//Fin du panier
} 
else echo "<p><font color=red>Panier vide!</font></p>
            <p><b><i>Si vous voulez recommencer cet exemple, cliquez <a href='?action=Recommencer'>ici</a></i></b></p>";
?> 
Remarque:
Il faut bien comprendre l'écriture suivante:
$panier["$réf"] et $panier["$réf"]["réf"]

Même si les deux indexes portent le même nom "réf", pour PHP ce n'est pas la même chose car le premier index ["$réf"] (où le mot "réf" est préfixé du $) désigne une variable qui a son évaluation donnera une valeur qui sera utilisée comme index.

Exemple:
si la variable $réf = 1
alors $panier["$réf"] = $panier["1"]

De ce fait, $panier["$ref"] désigne la ligne n°1 du tableau panier
De même $panier["$réf"]["réf"] sera $panier["1"]["réf"] si $réf=1 et désignera le champ "réf" de la ligne n°1 du tableau panier.

Cette technique d'indexation d'un tableau par la clé primaire d'une table de base de données est une bonne astuce pour simplifier les opérations nécessitant des accès directs dans le tableau, telque la recherche, l'ajout, la modif et la suppression.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Komoz
Invité n'ayant pas de compte PHPfrance

25 juin 2007, 15:17

Re sadeq, j'ai eu un contre-temps d'où ma réponse tardive.

Merci pour ton aide, mais je ne voudrais pas "griller" les étapes. Je veux essayer de faire mon truc comme un grand avec ton/votre aide. Nulle question de vouloir réinventer la roue ou créer The Application, mais juste faire un truc qui tourne avec mon cerveau et mes p'tites mains pour mélanger théorie et pratique. D'ailleurs dans mon tableau (j'étais vraiment fatigué), j'ai oublié le prix lol.

Peux-ton reprendre de mon exemple si possible avec la notion de prix en plus ? :oops:

Merci

Komoz

Invité
Invité n'ayant pas de compte PHPfrance

26 juin 2007, 11:54

Hey !

J'ai réussi à progresser et je comprends mieux certaines choses maintenant.

Dans l'exécution de mon script, je n'arrive pas à tester si un produit est déjà présent dans mon panier et si oui l'incrémenter de 1. Voici où j'en suis :
if (!isset($_SESSION['panier'])){//si le panier n'existe pas, il est créé
$_SESSION['panier'] = array();//le panier est un tableau qui contient un tableau
array_push($_SESSION['panier'],array("ref"=>$_POST['ref'],"qte"=>$_POST['qte']));
}else{//sinon c'est que le panier existe et qu'on ajoute le nouveau produit ou qu'on met à jour un déjà présent
$presence = array_search($_POST['ref'],$_SESSION['panier']);//test de présence
if ($presence==true){
$_SESSION['panier'][$presence]['qte']++;
}else{//sinon c'est un nouveau produit
array_push($_SESSION['panier'],array("ref"=>$_POST['ref'],"qte"=>$_POST['qte']));
}
}

//où en sommes-nous dans tout ça ?
echo '<pre>'; 
var_dump($_SESSION['panier']); 
echo '</pre>';

//retour au cata
echo '<a href="cata.php">retourner au cata</a>';
Si quelqu'un veut bien jeter un oeil et me filer un coup de main, ca serait sympa merci ;)

Komoz

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

26 juin 2007, 12:45

Tu dois nous dire d'abord que fait la fonction array_search() et comment imagines-tu le contenu du tableau $_SESSION["panier"]?

En répondant à ces deux questions tu pourras corriger ton programme pour réussir la recherche d'une référence d'article.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Komoz
Invité n'ayant pas de compte PHPfrance

26 juin 2007, 13:11

Merci sadeq de ton retour, ca fait du bien de pouvoir compter sur quelqu'un.

Pour répondre à tes questions, je vais tenter de m'expliquer clairement :

Avec l'array_search, je voulais vérifier si le produit était déjà présent ou non dans le tableau/session['panier']. Pour mon exemple comme je n'ai pas de base de données je travaille qu'avec de la saisie (pour me faire la main). En gros je retourne sur le formulaire initial (comme-ci j'accédai pour la première fois au "site"). Si je retape la même référence avec ma quantité et que cette référence est déjà dans le tableau, je l'incrémente d'autant que j'ai mis dans le champ quantité.

Avec mes nouvelles connaissances, j'imagine mon panier de la forme la plus simple et courante il me semble à savoir des tableaux imbriqués dans un tableau parent.

L'array général panier avec ses enregistrements formant à chaque fois un nouvel array indépendant. Voici ce que donne un :
echo '<pre>'; 
var_dump($_SESSION['panier']); 
echo '</pre>'; 
de mon array, tu vas mieux comprendre ;)

Code : Tout sélectionner

array(3) { [0]=> array(2) { ["ref"]=> string(3) "gta" ["qte"]=> string(1) "4" } [1]=> array(2) { ["ref"]=> string(3) "gta" ["qte"]=> string(1) "3" } [2]=> array(2) { ["ref"]=> string(3) "gta" ["qte"]=> string(2) "10" } }
Komoz

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

26 juin 2007, 16:59

Ok, c'est ce qu'on appelle un tableau à 2 dimensions.
un tableau à une dimension c'est l'exemple de
$t = array('A', 'B', 'C');
et ton panier est effectivement un tableau à 2 dimensions exemple:
$t = array (
                    array ('A', 'B', 'C') ,
                    array ('D', 'E', 'F') ,
                    array ('G', 'H', 'I') 
);
maintenant va voir sur la doc comment marche array_search() et tu va t'appercevoir rapidement de l'erreur que t'as commis dans ton code de recherche.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Komoz
Invité n'ayant pas de compte PHPfrance

26 juin 2007, 17:38

J'dois être miro (j'ai pourtant des lunettes), fatigué (assurément, 6h de sommeil en 2 jours) ou pas doué (probablement), car je vois rien à part le fait que l'array_search semble réserver à un tableau simple. C'était ce qu'il fallait voir ou j'ai zappé l'évidence ?

Komoz

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

26 juin 2007, 19:16

Tu n'a rien zappé, t'es lucide. Effectivement, array_search() s'attaque à un tableau à une dimension, cherche un critère dans ses différentes cases et renvoit l'index de la case où il le trouve sinon un équivalent à False (===False).

Exemple:
  • Dans le tableau $t = array('A', 'B', 'C');
    si tu cherche 'A' array_search() te retourne le n° de case 0
    si tu cherche 'B' array_search() te retourne le n° de case 1
    si tu cherche 'C' array_search() te retourne le n° de case 2
    si tu cherche 'D' array_search() te retourne ===False.
Mais puisque ton panier est un tableau à 2 dimensions, il faudra le parcourir ligne par ligne (tableau par tableau)

Toutefois si tu applique array_search() à chaque ligne de ton panier elle cherchera dans toutes les cases (à savoir 'ref' et 'qte') ce qui ne correspond pas exactement au critère de recherche car toi tu cherche seulement une 'ref' donnée mais pas la 'qte' donc array_search() n'est pas appropriée.

Ce qui serait judicieux est d'attaquer directement la case (colonne) 'ref' pour tester si égale au critère et si oui tu arrête la boucle de parcours en mémorisant le n° de la ligne où t'as trouvé.

En suite tu teste si un n° de ligne est trouvé, si oui tu incrémente la 'qte' sinon tu fais l'ajout.

Alors bon alogorithme :wink:

ps: Je t'invite à t'inscrire dans le Forum comme ça tu pourras suivre tes posts
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène