j'ai effecteur une pagination sur mes pages produits et un filtrage, tout marche sur la page 1 mais quand je passe sur la page 2 le filtrage n'est pas gardé.
Il me semble devoir passer le filtrage en session mais je bloque un peu voici mon code
<div class="chekbox">
<form name="nature" method="post" action="pipe-en-verre">
<legend> <div class="spoiler" onclick="ouvrirFermerSpoiler(this);"><?php echo _("Filtrer par types"); ?></legend>
<div class="contenuSpoiler">
<div>
<input type="checkbox" id="spoon pipes" name="nature" value="spoon pipes">
<label for="taille">spoon pipes</label>
</div>
<div>
<input type="checkbox" id="chillums" name="nature" value="chillums">
<label for="taille">chillums</label>
</div>
<div>
<input type="checkbox" id="pipes sherlock" name="nature" value="pipes sherlock">
<label for="taille">pipes sherlock</label>
</div>
<div>
<input type="checkbox" id="steamrollers" name="nature" value="steamrollers">
<label for="taille">steamrollers</label>
</div>
<div>
<input type="checkbox" id="" name="nature" value="all types">
<label for="nature"><?php echo _("tout types"); ?></label>
</div>
</div>
</div>
</form>
</div>
<?php $bdd = NEW PDO ("mysql:host= 3333;dbname=33333;charset=utf8","3333","33333");
$productperpage = 32;
if ($_POST['nature'] == "spoon pipes") {
$totalProduct = $bdd->query('SELECT id FROM products WHERE nature ="spoon pipes"');
}
elseif ($_POST['nature'] == "chillums") {
$totalProduct = $bdd->query('SELECT id FROM products WHERE nature ="chillums"');
}
elseif ($_POST['nature'] == "pipes sherlock") {
$totalProduct = $bdd->query('SELECT id FROM products WHERE nature ="pipes sherlock"');
}
elseif ($_POST['nature'] == "steamrollers") {
$totalProduct = $bdd->query('SELECT id FROM products WHERE nature ="steamrollers"');
}
elseif ($_POST['nature'] == "all types") {
$totalProduct = $bdd->query('SELECT id FROM products WHERE nature IN("spoon pipes", "chillums", "pipes sherlock", "steamrollers")');
}
elseif (empty($_POST['nature'])) {
$totalProduct = $bdd->query('SELECT id FROM products WHERE nature IN("spoon pipes", "chillums", "pipes sherlock", "steamrollers")');
}
$productTotal = $totalProduct->rowCount();
$pagesTotales = ceil($productTotal/$productperpage);
if (isset($_GET['page']) AND !empty($_GET['page'])AND $_GET['page'] > 0) {
$_GET['page'] = intval($_GET['page']);
$pageCourante = $_GET['page'];
} else {
$pageCourante = 1;
}
$depart = ($pageCourante-1)*$productperpage;
?>
C'est normal : tes variables $_POST n'existent plus dès que tu changes de page, il faut propager tes filtres en query string ($_GET) ou éventuellement en session (ce que je déconseille).
changer method="POST" en method="GET" (ou le supprimer/omettre vu que c'est la méthode par défaut)
modifier les $_POST pour $_GET
reproduire la query string (à l'exception du paramètre page) via http_build_query (j'ai dû donner ici la méthode plus d'une fois) (idéalement après un array_intersect_key histoire de ne pas reprendre n'importe quoi)
Pour remplacer : href="pipe-en-verre.php?page='.$i.'" par href="pipe-en-verre.php?' . http_build_query($qs + ['page' => $i], null, '&') . '"
Tu pourrais utiliser la syntaxe alternative et remplacer ton SELECT id puis rowCount non portable par un SELECT COUNT(*) (+ fetchColumn) qui serait aussi plus efficace.
Tu pourrais aussi regrouper les 2 derniers else if en un else surtout qu'actuellement si aucune condition n'est satisfaite, ça risque de planter
nature IN("spoon pipes", "chillums", "pipes sherlock", "steamrollers") si ce sont là toutes les valeurs possibles pour ta colonne nature tu peux supprimer la clause WHERE
> Pourquoi détruire la variable $_GET['page'] ???
Il est vrai que l'on pourrait faire autrement voir s'en passer en l'écrasant directement (quand elle existe) via un array_merge ou inversant tout simplement les opérandes du +. Réflexion faite, c'est peut être même potentiellement plus rapide à l'exécution de conserver la clé.
Petite coquille de ma part : c'est bien array_intersect_key et non array_interset_key
> $get = $_GET;
Je fais une copie de $_GET de façon à le garder intact, surtout si tu voulais retrouver $_GET['page'] par la suite
> unset($_GET['page']);
Ca aurait dû être unset($get['page']); (décidément), on supprime, si elle existe, la page courante (vu que le but est de la redéfinir sur chaque lien vers une page)
Le but du array_intersect_key + array_fill_keys est de ne conserver que le paramètre nature (du coup ça supprime déjà le paramètre page) et ainsi ne pas reprendre tout et n'importe quoi que l'on pourrait te passer par l'URL. Sinon si quelqu'un fait un lien vers ta page avec ?truc=bidule&foo=test, tu vas bêtement les recopier sur ta pagination.
Au final, tu peux juste écrire : $qs = array_intersect_key($_GET, array_fill_keys(['nature'], null)); (avant ta boucle for) puis faire tes liens avec . http_build_query(data: $qs + ['page' => $i], arg_separator: '&') .
alors $DB c'est surtout pour mon système de panier et ma boucle pour afficher les produits et $bdd c'étais les ajouts de code (pagination) que j'avais effectuer bien après c'est grave ou juste mal ordonnée?
- Edité par lutinjoyeux 2 décembre 2024 à 19:25:12
Il faudrait l'ensemble, là on ne sait pas si la connection est faite avec PDO ou pas. On ne sait pas non plus, pour PDO, si tu redéfinissais le mode de fetch par défaut à un moment ou à un autre ou non.
erf, d'un côté tu as directement une instance PDO qui est certainement en mode PDO::FETCH_BOTH (= renvoie un tableau) et de l'autre un wrapper qui retourne tout en PDO::FETCH_OBJ (renvoie des objets stdclass).
Soit :
tu gardes (et utilises) ta classe au lieu de PDO et tu changes tes $ligne['colonne'] en $ligne->colonne
tu utilises directement PDO et tu changes tes $ligne->colonne en $ligne['colonne']
tu utilises directement PDO et tu redéfinis le mode par défaut (soit globalement à la connexion) soit pour chaque requête mais dans ce dernier cas, ça va vite devenir un problème si tu n'utilises jamais le même
ok merci par contre je vois déjà pas ce que sont les $ligne['colonne'] et vu que ce code me sert pour mon panier je préfère ne pas y toucher je vais laisser avec les 2
connexion je pence parce que la sa se complique trop pour moi
$ligne['colonne'] : c'est une manière de dire pour $ligne de la base de données, sous forme de tableau, on accède à la ['colonne'] avec cette syntaxe. C'est par défaut la manière de faire avec PDO, d'après tes explications celle utilisée pour ton panier ;
$ligne->colonne : pratiquement la même chose, mais quand c'est utilisé avec PDO::FETCH_OBJ, $ligne n'est plus un tableau mais un objet, et du on accède à la ->colonne avec cette autre syntaxe. C'est la méthode que tu utilises avec $product->name, $product->price, etc.
En résumé, ce que julp te propose fort pertinemment par rapport à ce que tu mentionnes :
changer d'une syntaxe à l'autre là où tu as le problème ;
t'assurer de devoir utiliser la même syntaxe avec $bdd et $db pour éviter d'être chauve avant l'heure.
Même si on nous dira que ça fonctionne, cette ligne est pour remonter le temps à PHP 5.3.6 et moins. Plutôt que cela, il est conseillé d'ajouter (concaténer) ;charset=utf8 au premier paramètre passé à PDO.
ce que je comprend pas trop c'est pourquoi changer $ligne['colonne'] alors que j'ai juste une deuxième connection différente pour la pagination du coup c'est au niveau du code de la pagination que je doit changer ?
<?php $bdd = NEW PDO ("");
$productperpage = 32;
if (isset($_GET['nature'])) {
$nature = $_GET['nature'];
}else{
$nature = null;
}
$get = $_GET;
if ($nature == "spoon pipes") {
$totalProduct = $bdd->query('SELECT COUNT(*) FROM products WHERE nature ="spoon pipes"');
}
elseif ($nature == "chillums") {
$totalProduct = $bdd->query('SELECT COUNT(*) FROM products WHERE nature ="chillums"');
}
elseif ($nature == "pipes sherlock") {
$totalProduct = $bdd->query('SELECT COUNT(*) FROM products WHERE nature ="pipes sherlock"');
}
elseif ($nature == "steamrollers") {
$totalProduct = $bdd->query('SELECT COUNT(*) FROM products WHERE nature ="steamrollers"');
}
else{
$totalProduct = $bdd->query('SELECT COUNT(*) FROM products WHERE nature IN("spoon pipes", "chillums", "pipes sherlock", "steamrollers")');
}
$productTotal = $totalProduct->fetchColumn();
$pagesTotales = ceil($productTotal/$productperpage);
if (isset($_GET['page']) AND !empty($_GET['page'])AND $_GET['page'] > 0) {
$_GET['page'] = intval($_GET['page']);
$pageCourante = $_GET['page'];
} else {
$pageCourante = 1;
}
$depart = ($pageCourante-1)*$productperpage;
unset($_GET['page']);
?>
- Edité par lutinjoyeux 3 décembre 2024 à 14:27:03
Parce qu'il n'y a à mon sens pas de raison d'avoir deux connexions à la même base de données et deux manières de faire qui en découlent.
Mais il n'est pas impossible que l'erreur que tu mentionnais vienne d'une erreur dans la requête une fois les concaténations effectuées. Pour éviter cela, on utilise volontiers les requêtes préparées, ce qui apporte aussi un gain de sécurité.
Si on avait eu le message d'erreur complet, on aurait pu mieux cerner le problème, on est parti sur l'idée que tu avais quelque part des résultats sous forme de tableaux plutôt que d'objets. Or, il y a une autre possibilité.
Bref, est-ce que tu pourrais nous donner l'entier du message d'erreur, et non une version nettoyée comme dans ce message ?
erreur obtenu en changeant cette partie du code (pagination)
<?php
$productperpage = 32;
if (isset($_GET['nature'])) {
$nature = $_GET['nature'];
}else{
$nature = null;
}
$get = $_GET;
if ($nature == "spoon pipes") {
$totalProduct = $DB->query('SELECT id FROM products WHERE nature ="spoon pipes"');
}
elseif ($nature == "chillums") {
$totalProduct = $DB->query('SELECT id FROM products WHERE nature ="chillums"');
}
elseif ($nature == "pipes sherlock") {
$totalProduct = $DB->query('SELECT id FROM products WHERE nature ="pipes sherlock"');
}
elseif ($nature == "steamrollers") {
$totalProduct = $DB->query('SELECT id FROM products WHERE nature ="steamrollers"');
}
else{
$totalProduct = $DB->query('SELECT id FROM products WHERE nature IN("spoon pipes", "chillums", "pipes sherlock", "steamrollers")');
}
$productTotal = $totalProduct->rowCount();
$pagesTotales = ceil($productTotal/$productperpage);
if (isset($_GET['page']) AND !empty($_GET['page'])AND $_GET['page'] > 0) {
$_GET['page'] = intval($_GET['page']);
$pageCourante = $_GET['page'];
} else {
$pageCourante = 1;
}
$depart = ($pageCourante-1)*$productperpage;
unset($_GET['page']);
?>
Fatal error: Uncaught Error: Call to a member function rowCount() on array in /homepages/produit/pipe-en-verre.php:143 Stack trace: #0 {main} thrown in /homepages/produit/pipe-en-verre.php on line 143
$productTotal = $totalProduct->rowCount();
- Edité par lutinjoyeux 3 décembre 2024 à 14:51:29
Uncaught Error: Call to a member function fetchColumn() on array in /homepages/produit/pipe-en-verre.php:143 Stack trace: #0 {main} thrown in /homepages/30/d752321604/htdocs/produit/pipe-en-verre.php on line 143
le problême viendrait pas
de
$req->fetchAll(PDO::FETCH_OBJ);
utiliser pour mon panier et ma boucle foreach pour afficher mes produits ?
du coup je dois refaire une recuperation des produits avec
->fetchAll(PDO::FETCH_ASSOC);
pour ma pagination ????
- Edité par lutinjoyeux 3 décembre 2024 à 15:34:53
Si tu modifies du code dans des messages précédant des réponses déjà faites et donc qui se basent dessus, on ne va pas s'en sortir, autant jouer au kamoulox, mais ce n'est pas le bon forum.
Avec le (nouveau) code fourni, je ne comprends pas le besoin d'une boucle pour la pagination, le problème mentionné au moment de répondre ne vient pas de là. Tu y utilises ta classe DB, dont la méthode query() retourne un tableau de résultats, et non quelque chose sur quoi tu peux appeler rowCount(). D'où le conseil de julp de ne pas mélanger les deux méthodes de connexion.
Pour calculer le nombre de pages avec ce code au moment de la réponse, il faut du coup compter le nombre d'éléments qu'il y a dans $totalProduits.
<?php
$productperpage = 32;
if (isset($_GET['nature'])) {
$nature = $_GET['nature'];
}else{
$nature = null;
}
$get = $_GET;
if ($nature == "spoon pipes") {
$totalProduct = $DB->query('SELECT * FROM products WHERE nature ="spoon pipes"');
}
elseif ($nature == "chillums") {
$totalProduct = $DB->query('SELECT * FROM products WHERE nature ="chillums"');
}
elseif ($nature == "pipes sherlock") {
$totalProduct = $DB->query('SELECT * FROM products WHERE nature ="pipes sherlock"');
}
elseif ($nature == "steamrollers") {
$totalProduct = $DB->query('SELECT * FROM products WHERE nature ="steamrollers"');
}
else{
$totalProduct = $DB->query('SELECT * FROM products WHERE nature IN("spoon pipes", "chillums", "pipes sherlock", "steamrollers")');
}
$productTotal = $totalProduct->count();
$pagesTotales = ceil($productTotal/$productperpage);
if (isset($_GET['page']) AND !empty($_GET['page'])AND $_GET['page'] > 0) {
$_GET['page'] = intval($_GET['page']);
$pageCourante = $_GET['page'];
} else {
$pageCourante = 1;
}
$depart = ($pageCourante-1)*$productperpage;
unset($_GET['page']);
?>
du coup j'ai modifier avec count mais j#ai toujours l'erreur 143 Fatal error: Uncaught Error: Call to a member function count() on array in /homepages//produit/pipe-en-verre.php:143 Stack trace: #0 {main} thrown in /homepages/30/d752321604/htdocs/satyr/produit/pipe-en-verre.php on line 143
- Edité par lutinjoyeux 3 décembre 2024 à 15:48:20
Comme le dit le message d'erreur, $totalProduct est un tableau. Comment compter les éléments d'un tableau ?
En tout cas, ce n'est pas en tentant d'appeler une méthode dessus. Une méthode, qui est appelée avec l'opérateur -> et des parenthèses, est une fonction d'un objet. Un tableau n'est pas un objet en PHP.
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
ce que je comprend pas trop c'est pourquoi changer $ligne['colonne'] alors que j'ai juste une deuxième connection différente pour la pagination du coup c'est au niveau du code de la pagination que je doit changer ?
du coup j'ai modifier avec count mais j#ai toujours l'erreur 143