[RESOLU] Supprimer un sous-tableau en PHP et l'enregistrer dans un cookie

Eléphanteau du PHP | 10 Messages

31 janv. 2023, 17:34

Bonjour,

je suis en train de faire un panier d'E-commerce où les produits sélectionnés par l'utilisateur sont sauvegardé dans un cookie (ce n'est pas le plus optimal/safe, je sais, mais c'est pour un exercice d'une formation donc je n'ai pas le choix).

Pour faire simple, j'ai ma page index.php avec une liste de produits, quand on sélectionne un produit cela créer un cookie (qui reste 2 semaines) qui va enregistrer quel produit a été sélectionné sous forme de tableau multidimensionnel (premier tableau avec des key différentes (que je vais appeler key de commande) avec pour valeur d'autres tableaux comportant les information du produit (nom, prix)).

Puis une page shopping_cart.php, qui restitue les données du cookie et les affiches. Jusque là, tout fonctionne très bien, le cookie se met bien à jour quand je sélectionne un produit et les affiche correctement dans le panier.

Voici le problème: j'essaye d'ajouter une fonction "delete" pour retirer un produit du panier. Pour ce faire, j'ai fais en sorte que cela supprime la key de commande correspondant au produit qu'on veut retirer avant de remettre à jour le cookie. Là encore, quand j'essaye, ça semble bien fonctionner et bien enlever l'item souhaité, sauf que c'est là où ça casse.

En effet, à partir de ce moment là, quand je retourne sur index.php, le cookie n'a pas pris en compte ce que j'ai enlevé. J'ai checké en faisant un print_r de la valeur du cookie à la fois sur index.php, sur shopping_cart.php ainsi que sur une page test.php qui servirait de base témoin, pour voir ce que le cookie prend comme information. Et là où avant tout fonctionnait très bien, dès que je "delete" un produit, le cookie semble se mettre à jour (il enlève bel et bien la ligne de la commande dans les données, et le cookie est donc à jour sur shopping_cart.php ainsi que sur test.php), mais quand je reviens sur index.php, il garde ses anciens attribus. Plus bizarre encore, quand je rajoute des produits au panier, ces derniers s'affichent sur le cookie d'index.php, mais pas sur les cookies de shopping_cart.php et test.php, alors que ce sont les même cookies!

Du coup j'imagine qu'il y a un endroit où j'ai dû me tromper dans le code, notamment au moment de delete un produit du panier, mais ce que je comprends pas c'est que tout semble fonctionner en dehors de ça, et je ne vois pas pourquoi les données du cookie change d'une page à l'autre.

Désolé pour le pavé, j'espère juste pouvoir trouver un début de piste ici.

Voici ma page index.php
<?php require ("site/inc_connexion.php"); ?>
<?php

if(isset($_POST['add_to_cart'])) //si on appuie sur ajouter
{

	$select_item_id = $_POST['hidden_id']; // on récupère les données de "ajouter"
	$select_item_name = $_POST['hidden_name'];
	$select_item_price = $_POST['hidden_price'];

	$item_array = array( //on met ces données sous forme de tableau
	'item_id' => $select_item_id,
	'item_name' => $select_item_name,
	'item_price' => $select_item_price
	);

	if(isset($_COOKIE['new1'])) //on vérfie si le cookie existe
	{

 		// on restitu les données du cookie
		$cookie_data = unserialize($_COOKIE['new1']);

		$cookie_data[] = $item_array; //on rajoute au cookie les nouvelles valeurs
		$cookie_data = serialize($cookie_data);

		// on reset un cookie avec les nouvelles valeurs
		setcookie ('new1', $cookie_data, time() + 1296000);

	}
	else // le cookie n'existe pas, alors on le créer
	{
		$cookie_data[] = $item_array;
		$cookie_data = serialize($cookie_data);
		setcookie('new1', $cookie_data, time() + 1296000);
	}
}

?>

<!DOCTYPE html>
<html lang="fr">
<head>
	<meta charset="utf-8">
	<title>E-commerce</title>

	 <!--Description du site-->
    <meta name="description" content="Site d'E-commerce">

    <!--IE navigateur-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <!-- css -->
    <link href="css/reset.css" rel="stylesheet" type="text/css">
	<link href="css/style.css" rel="stylesheet" type="text/css">
</head>

<body>

<?php // On prend dans les infos dans la base de donnée
$result = $mysqli->query('SELECT item_ID, item_name, item_price FROM items');
foreach ($result as $row):
	$item_id = $row['item_ID'];
	$item_name = $row['item_name'];
	$item_price = $row['item_price'];
?>

<form method="post">

<?php echo $item_name?> à <?php echo $item_price ?> euros<br>
<input type="hidden" name="hidden_id" value="<?php echo $item_id ; ?>" />
<input type="hidden" name="hidden_name" value="<?php echo $item_name ; ?>" />
<input type="hidden" name="hidden_price" value="<?php echo $item_price ; ?>" />
<input type="submit" name="add_to_cart" value="add to cart">

</form>
<?php endforeach ?>

<a href="site/shopping_cart.php">Voir le panier</a>
<a href="site/cookie.php">Voir le cookie</a>

</body>
</html>
ma page shopping_cart.php
<?php

if(isset($_COOKIE['new1'])) // si le cookie existe
{
	// on restitu les données du cookie et créer le total
	$total = 0;
	$cookie_data = unserialize($_COOKIE['new1']);

	// on affiche la restitution des données du cookie
	foreach ($cookie_data as $key => $selected_item) 
	{ 
		echo "<ul>"; // on rajoute la possibilité de delete l'item
		echo "<li>" . $selected_item['item_name'] . " à " . $selected_item['item_price'] . "euros et dont l'itme_id est " . $selected_item['item_id'] . "et son id de commande est" . $key . "<a href='shopping_cart.php?action=delete&add_id=" . $key . "'>Remove item</a></li>";
		echo "</ul>";

		// on fait le total des prix de la liste
		$total = $total + ($selected_item['item_price']);
	}

	echo "<br>" . $total . "euros<br>" ;
}
else // le cookie n'existe pas encore
{
	echo "vous n'avez encore rien commandé";
}

if(isset($_GET['action'])) //si on reçoit la demande d'une action
{
	if($_GET['action'] == "delete") //si l'action est delete
	{
		foreach ($cookie_data as $key => $selected_item) // on cherche la bonne key de la commande
		{
			if($key == $_GET['add_id']) // si le delete correspond à la key de la commande
			{
				unset($cookie_data[$key]); // enlever la commande correspondant à la key des données

				// on reset un cookie avec les nouvelles valeurs
				$cookie_data = serialize($cookie_data);
				setcookie ('new1', $cookie_data, time() + 1296000); 
			}
		}
	}
}
?>

<!DOCTYPE html>
<html lang="fr">
<head>
	<meta charset="utf-8">
	<title>E-commerce</title>

	 <!--Description du site-->
    <meta name="description" content="Site d'E-commerce">

    <!--IE navigateur-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <!-- css -->
    <link href="css/reset.css" rel="stylesheet" type="text/css">
	<link href="css/style.css" rel="stylesheet" type="text/css">
</head>

<body>

<a href="../index.php">retour à la liste </a><br>
<a href="cookie.php">Voir le cookie</a>

</body>
</html>
et ma page test du cookie, test.php
<?php require ("inc_connexion.php"); ?>
<?php
if(isset($_COOKIE['new1'])) //on vérfie si le cookie existe
{

 // on restitu les données du cookie
$cookie_data = unserialize($_COOKIE['new1']);
	echo "<pre>";
	print_r($cookie_data);
	echo "</pre>";

	}
?>
Je précise que pour l'instant y a 0 mise en page de mes documents, j'essaye d'abord de faire quelque chose de fonctionnel

Avatar du membre
Mammouth du PHP | 1303 Messages

31 janv. 2023, 19:36

Pourquoi utiliser unserialize() qui est dangereux d'après la DOC ?

Insère le contenu de ton caddie en JSON avec json_encode et récupère le avec json_decode (la DOC le préconise : https://www.php.net/manual/fr/function.unserialize.php).

Essaye déjà avec JSON.

Si t'as le choix, insère que les ID de produit dans ton caddie puis fait un foreach en vérifiant si l'ID existe en BDD puis t'affiche les infos qui sont DANS la BDD.

Eléphanteau du PHP | 10 Messages

31 janv. 2023, 20:14

Pourquoi utiliser unserialize() qui est dangereux d'après la DOC ?

Insère le contenu de ton caddie en JSON avec json_encode et récupère le avec json_decode (la DOC le préconise : https://www.php.net/manual/fr/function.unserialize.php).

Essaye déjà avec JSON.

Si t'as le choix, insère que les ID de produit dans ton caddie puis fait un foreach en vérifiant si l'ID existe en BDD puis t'affiche les infos qui sont DANS la BDD.
Merci pour la réponse!
J'utilise serialize() et unserialize() parce que c'est ce qu'on a vu en cour (on n'a pas vu JSON), après comme je l'ai précisé ici c'est juste une question d'exercice pour comprendre les mécanismes, pas de faire quelque chose d'optimisé, sûr ni qui servirait dans un vrai site.

Et effectivement insérer uniquement les ID ça optimise la chose, je m'occuperai des optimisations ensuite si possible, là pour l'instant je cherche à faire quelque chose de fonctionnel.

Mais du coup, que ce soit le fait d'utiliser JSON ou les ID uniquement, le problème de cookie reste le même et ça ne m'indique pas pourquoi mes pages réagissent comme ça o:

Avatar du membre
Mammouth du PHP | 1303 Messages

31 janv. 2023, 20:53

J'utilise serialize() et unserialize() parce que c'est ce qu'on a vu en cour (on n'a pas vu JSON), après comme je l'ai précisé ici c'est juste une question d'exercice pour comprendre les mécanismes, pas de faire quelque chose d'optimisé, sûr ni qui servirait dans un vrai site.

Et effectivement insérer uniquement les ID ça optimise la chose, je m'occuperai des optimisations ensuite si possible, là pour l'instant je cherche à faire quelque chose de fonctionnel.
Si tu à le droit d'optimiser le cookies, octroit toi le droit de passer en JSON, ce sera une bonne façon de faire et ça résoudra même ton problème si il faut ;)
Mais du coup, que ce soit le fait d'utiliser JSON ou les ID uniquement, le problème de cookie reste le même et ça ne m'indique pas pourquoi mes pages réagissent comme ça o:
As tu essayé avec le format JSON ?

Eléphanteau du PHP | 10 Messages

31 janv. 2023, 23:42

J'utilise serialize() et unserialize() parce que c'est ce qu'on a vu en cour (on n'a pas vu JSON), après comme je l'ai précisé ici c'est juste une question d'exercice pour comprendre les mécanismes, pas de faire quelque chose d'optimisé, sûr ni qui servirait dans un vrai site.

Et effectivement insérer uniquement les ID ça optimise la chose, je m'occuperai des optimisations ensuite si possible, là pour l'instant je cherche à faire quelque chose de fonctionnel.
Si tu à le droit d'optimiser le cookies, octroit toi le droit de passer en JSON, ce sera une bonne façon de faire et ça résoudra même ton problème si il faut ;)
Mais du coup, que ce soit le fait d'utiliser JSON ou les ID uniquement, le problème de cookie reste le même et ça ne m'indique pas pourquoi mes pages réagissent comme ça o:
As tu essayé avec le format JSON ?
Oui je vais clairement optimiser tout ça par la suite, là c'était surtout pour comprendre d'où venait le problème, et j'ai trouvé!
Le index.php n'est pas dans le même fichier que shopping_cart.php et test.php, ces deux là sont un fichier à part qui est dans le même fichier qu'index.php (en gros dans l'arborescence, l'index.php est un cran au-dessus), or les informations du cookies se transmettent correctement vers les pages php qui sont dans le même fichier ET dans un fichier dessous, mais les informations ne se transmettent pas vers une page qui se trouve dans un fichier au-dessus... Alors pourquoi, j'en ai aucune idée, mais en descendant index.php au même niveau que les autres pages, ou en remontant ces dernières au même niveau qu'index.php, sans rien changer au code, ça fonctionne! C'était tout con en fait, j'aurais bien aimé que nos cours le précise en tout cas...

Quoiqu'il en soit, merci pour les conseils et pour le format JSON, c'est bien mieux en effet :)

Avatar du membre
Mammouth du PHP | 1303 Messages

31 janv. 2023, 23:59

Regarde les paramètres de la fonction setCookie de PHP, tu peux définir si c'est pour tout le domaine ou un dossier il me semble.

Eléphanteau du PHP | 10 Messages

01 févr. 2023, 00:26

Regarde les paramètres de la fonction setCookie de PHP, tu peux définir si c'est pour tout le domaine ou un dossier il me semble.
Merci du conseil! je savais pas qu'on pouvait le faire, je vais checker ça, c'est vrai que ça serait bien utile pour le coup! :)