Système de panier d'achat avec PHP et MySQL

 


Système de panier d'achat avec PHP et MySQL

Dans ce tutoriel, nous allons créer un système de panier d'achat avec PHP et MySQL. Le système de panier d'achat permettra aux visiteurs de nos sites Web de parcourir les produits, d'ajouter des produits au panier et de passer des commandes.

Nous utiliserons l' interface PDO pour accéder à notre base de données MySQL avec PHP car cela nous facilitera grandement l'interaction avec notre base de données et la manipulation de nos tables.

Le système de panier que nous allons créer contiendra 4 produits. Ces produits ne sont essentiellement que des gadgets/accessoires que nous utiliserons comme exemples pour ce didacticiel. Vous pouvez ajouter vos propres produits plus tard dans le didacticiel.



1. Mise en route

Nous devons suivre quelques étapes avant de créer notre système de panier d'achat. Nous devons configurer notre environnement de serveur Web (si vous ne l'avez pas déjà fait) et nous assurer que les extensions requises sont activées.

1.1. Démos

Vous trouverez ci-dessous des liens vers les démonstrations du panier d'achat. La démo du didacticiel est ce que nous allons créer. La démo avancée est le package que vous pouvez acheter à la fin du message. Cela inclut plus de fonctionnalités et un lien de téléchargement vers le code source.

1.2. Exigences

  • Si vous n'avez pas de configuration de serveur Web local, vous devez télécharger et installer XAMPP .
  • Assurez-vous que l'extension PDO est activée (elle doit être incluse et activée par défaut).

1.3. Ce que vous apprendrez dans ce tutoriel

  • Conception de modèles - Concevez une page d'accueil, une page de produits, une page de produits, une page de panier d'achat et une page de commande avec HTML5 et CSS3, et apprenez à implémenter le système de modèles PHP avec HTML.
  • Requêtes GET et POST — Créez des formulaires HTML et gérez les requêtes de données avec PHP.
  • Requêtes SQL préparées — Comment préparer les requêtes SQL pour empêcher l'injection SQL.
  • Validation de base — Validation des données de formulaire envoyées au serveur.
  • Gestion des sessions — Initialisez les sessions et stockez les produits du panier.

1.4. Structure et configuration des fichiers

Nous pouvons maintenant démarrer notre serveur Web et créer les fichiers et répertoires que nous allons utiliser pour notre système de panier.

  • Ouvrez le panneau de configuration XAMPP
  • À côté du module Apache, cliquez sur Démarrer
  • À côté du module MySQL, cliquez sur Démarrer
  • Accédez au répertoire d'installation de XAMPP ( C:\xampp )
  • Ouvrez le répertoire htdocs
  • Créez les répertoires et fichiers suivants :

Structure du fichier

\-- panier |
-- fonctions.php
|-- index.php
|-- accueil.php
|-- produits.php
|-- produit.php
|-- panier.php
|-- placeorder.php
|-- style .css
\-- imgs
|-- image-vedette.jpg
|-- appareil photo.jpg
| -- casque.jpg
| -- portefeuille.jpg
|-- montre.jpg

Chaque fichier/répertoire contiendra les éléments suivants :

  • functions.php — Ce fichier contiendra toutes les fonctions dont nous avons besoin pour notre système de panier (en-tête de modèle, pied de page de modèle et fonctions de connexion à la base de données).
  • index.php — Ce fichier contiendra le modèle principal (en-tête, pied de page, etc.) et le routage de base afin que nous puissions inclure les pages ci-dessous.
  • home.php — Ce fichier sera la page d'accueil qui contiendra une image vedette et 4 produits récemment ajoutés.
  • products.php — Ce fichier servira à afficher tous les produits avec une pagination de base.
  • product.php — Ce fichier affichera un produit (selon la requête GET) et contiendra un formulaire qui permettra au client de modifier la quantité et d'ajouter au panier le produit.
  • cart.php — La page du panier qui remplira tous les produits qui ont été ajoutés au panier, ainsi que les quantités, les prix totaux et le prix du sous-total.
  • placeorder.php — Un message de base qui sera affiché à l'utilisateur lorsqu'il passe une commande.
  • style.css — La feuille de style (CSS3) que nous utiliserons pour notre site Web de panier d'achat.
  • imgs — Répertoire qui contiendra toutes les images de notre système de panier d'achat (images en vedette, images de produits, etc.). Vous pouvez télécharger les exemples d'images en cliquant sur le nom du fichier dans le conteneur de structure de fichiers.

2. Création de la base de données et configuration des tables

Pour cette partie, vous devrez accéder à votre base de données MySQL, soit en utilisant phpMyAdmin , soit votre application de gestion de base de données MySQL préférée.

Si vous utilisez phpMyAdmin , suivez ces instructions :

  • Accédez à http://localhost/phpmyadmin/
  • Cliquez sur l' onglet Bases de données en haut
  • Sous Créer une base de données , saisissez panier dans la zone de texte
  • Sélectionnez utf8_general_ci comme collation (UTF-8 est l'encodage par défaut dans HTML5)
  • Cliquez sur Créer

N'hésitez pas à utiliser votre propre nom de base de données ou à utiliser shoppingcart comme nom de base de données.

Nous pouvons maintenant procéder à la création de la table des produits . Nous utiliserons cette table pour stocker tous nos produits, ainsi que le nom du produit, la description, l'image, le prix, le prix RRP, la quantité et la date d'ajout. Nous retrouverons ces produits plus tard dans le tutoriel avec PHP.

Cliquez sur la base de données dans le panneau de gauche ( panier ) et exécutez l'instruction SQL suivante :

SQLCopie
CREATE TABLE IF NOT EXISTS `products` (
	`id` int(11) NOT NULL AUTO_INCREMENT,
	`name` varchar(200) NOT NULL,
	`desc` text NOT NULL,
	`price` decimal(7,2) NOT NULL,
	`rrp` decimal(7,2) NOT NULL DEFAULT '0.00',
	`quantity` int(11) NOT NULL,
	`img` text NOT NULL,
	`date_added` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

INSERT INTO `products` (`id`, `name`, `desc`, `price`, `rrp`, `quantity`, `img`, `date_added`) VALUES
(1, 'Smart Watch', '<p>Unique watch made with stainless steel, ideal for those that prefer interative watches.</p>\r\n<h3>Features</h3>\r\n<ul>\r\n<li>Powered by Android with built-in apps.</li>\r\n<li>Adjustable to fit most.</li>\r\n<li>Long battery life, continuous wear for up to 2 days.</li>\r\n<li>Lightweight design, comfort on your wrist.</li>\r\n</ul>', '29.99', '0.00', 10, 'watch.jpg', '2019-03-13 17:55:22'),
(2, 'Wallet', '', '14.99', '19.99', 34, 'wallet.jpg', '2019-03-13 18:52:49'),
(3, 'Headphones', '', '19.99', '0.00', 23, 'headphones.jpg', '2019-03-13 18:47:56'),
(4, 'Digital Camera', '', '69.99', '0.00', 7, 'camera.jpg', '2019-03-13 17:42:04');

Sur phpMyAdmin , cela devrait ressembler à :

http://localhost/phpmyadmin/
Tableau des produits MySQL

Le code d'instruction SQL ci-dessus créera la table des produits avec les colonnes suivantes :

  • id— Identifiant unique pour le produit, celui-ci sera automatiquement incrémenté.
  • name— Le nom du produit.
  • desc— La description du produit.
  • price— Le prix du produit.
  • rrp— Le prix de détail, si vous voulez un produit en solde vous mettez la valeur plus haut que le prix.
  • date_added— La date à laquelle le produit a été ajouté, nous l'utiliserons pour trier les produits.

L'instruction SQL insérera également 4 exemples de produits que nous pouvons utiliser à des fins de test. Vous pouvez les modifier/supprimer plus tard dans le didacticiel lorsque nous aurons implémenté le code.

3. Conception du système de panier d'achat avec CSS

Au lieu d'utiliser une bibliothèque telle que Bootstrap , j'ai décidé de créer un design épuré, net et moderne avec du CSS3 pur .


Modifiez le fichier style.css et ajoutez le code suivant :

CSSCopie
* {
	box-sizing: border-box;
	font-family: -apple-system, BlinkMacSystemFont, "segoe ui", roboto, oxygen, ubuntu, cantarell, "fira sans", "droid sans", "helvetica neue", Arial, sans-serif;
	font-size: 16px;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}
html {
	height: 100%;
}
body {
	position: relative;
	min-height: 100%;
	color: #555555;
	background-color: #FFFFFF;
	margin: 0;
	padding-bottom: 100px; /* Same height as footer */
}
h1, h2, h3, h4, h5 {
	color: #394352;
}
.content-wrapper {
	width: 1050px;
	margin: 0 auto;
}
header {
	border-bottom: 1px solid #EEEEEE;
}
header .content-wrapper {
	display: flex;
}
header h1 {
	display: flex;
	flex-grow: 1;
	flex-basis: 0;
	font-size: 20px;
	margin: 0;
	padding: 24px 0;
}
header nav {
	display: flex;
	flex-grow: 1;
	flex-basis: 0;
	justify-content: center;
	align-items: center;
}
header nav a {
	text-decoration: none;
	color: #555555;
	padding: 10px 10px;
	margin: 0 10px;
}
header nav a:hover {
	border-bottom: 1px solid #aaa;
}
header .link-icons {
	display: flex;
	flex-grow: 1;
	flex-basis: 0;
	justify-content: flex-end;
	align-items: center;
	position: relative;
}
header .link-icons a {
	text-decoration: none;
	color: #394352;
	padding: 0 10px;
}
header .link-icons a:hover {
	color: #4e5c70;
}
header .link-icons a i {
	font-size: 18px;
}
header .link-icons a span {
	display: inline-block;
	text-align: center;
	background-color: #63748e;
	border-radius: 50%;
	color: #FFFFFF;
	font-size: 12px;
	line-height: 16px;
	width: 16px;
	height: 16px;
	font-weight: bold;
	position: absolute;
	top: 22px;
	right: 0;
}
main .featured {
	display: flex;
	flex-direction: column;
	background-image: url(imgs/featured-image.jpg);
	background-repeat: no-repeat;
	background-size: cover;
	height: 500px;
	align-items: center;
	justify-content: center;
	text-align: center;
}
main .featured h2 {
	display: inline-block;
	margin: 0;
	width: 1050px;
	font-family: Rockwell, Courier Bold, Courier, Georgia, Times, Times New Roman, serif;
	font-size: 68px;
	color: #FFFFFF;
	padding-bottom: 10px;
}
main .featured p {
	display: inline-block;
	margin: 0;
	width: 1050px;
	font-size: 24px;
	color: #FFFFFF;
}
main .recentlyadded h2 {
	display: block;
	font-weight: normal;
	margin: 0;
	padding: 40px 0;
	font-size: 24px;
	text-align: center;
	width: 100%;
	border-bottom: 1px solid #EEEEEE;
}
main .recentlyadded .products, main .products .products-wrapper {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	padding: 40px 0 0 0;
}
main .recentlyadded .products .product, main .products .products-wrapper .product {
	display: block;
	overflow: hidden;
	text-decoration: none;
	width: 25%;
	padding-bottom: 60px;
}
main .recentlyadded .products .product img, main .products .products-wrapper .product img {
	transform: scale(1);
	transition: transform 1s;
}
main .recentlyadded .products .product .name, main .products .products-wrapper .product .name {
	display: block;
	color: #555555;
	padding: 20px 0 2px 0;
}
main .recentlyadded .products .product .price, main .products .products-wrapper .product .price {
	display: block;
	color: #999999;
}
main .recentlyadded .products .product .rrp, main .products .products-wrapper .product .rrp {
	color: #BBBBBB;
	text-decoration: line-through;
}
main .recentlyadded .products .product:hover img, main .products .products-wrapper .product:hover img {
	transform: scale(1.05);
	transition: transform 1s;
}
main .recentlyadded .products .product:hover .name, main .products .products-wrapper .product:hover .name {
	text-decoration: underline;
}
main > .product {
	display: flex;
	padding: 40px 0;
}
main > .product > div {
	padding-left: 15px;
}
main > .product h1 {
	font-size: 34px;
	font-weight: normal;
	margin: 0;
	padding: 20px 0 10px 0;
}
main > .product .price {
	display: block;
	font-size: 22px;
	color: #999999;
}
main > .product .rrp {
	color: #BBBBBB;
	text-decoration: line-through;
	font-size: 22px;
	padding-left: 5px;
}
main > .product form {
	display: flex;
	flex-flow: column;
	margin: 40px 0;
}
main > .product form input[type="number"] {
	width: 400px;
	padding: 10px;
	margin-bottom: 15px;
	border: 1px solid #ccc;
	color: #555555;
	border-radius: 5px;
}
main > .product form input[type="submit"] {
	background: #4e5c70;
	border: 0;
	color: #FFFFFF;
	width: 400px;
	padding: 12px 0;
	text-transform: uppercase;
	font-size: 14px;
	font-weight: bold;
	border-radius: 5px;
	cursor: pointer;
}
main > .product form input[type="submit"]:hover {
	background: #434f61;
}
main > .products h1 {
	display: block;
	font-weight: normal;
	margin: 0;
	padding: 40px 0;
	font-size: 24px;
	text-align: center;
	width: 100%;
}
main > .products .buttons {
	text-align: right;
	padding-bottom: 40px;
}
main > .products .buttons a {
	display: inline-block;
	text-decoration: none;
	margin-left: 5px;
	padding: 12px 20px;
	border: 0;
	background: #4e5c70;
	color: #FFFFFF;
	font-size: 14px;
	font-weight: bold;
	border-radius: 5px;
}
main > .products .buttons a:hover {
	background: #434f61;
}
main .cart h1 {
	display: block;
	font-weight: normal;
	margin: 0;
	padding: 40px 0;
	font-size: 24px;
	text-align: center;
	width: 100%;
}
main .cart table {
	width: 100%;
}
main .cart table thead td {
	padding: 30px 0;
	border-bottom: 1px solid #EEEEEE;
}
main .cart table thead td:last-child {
	text-align: right;
}
main .cart table tbody td {
	padding: 20px 0;
	border-bottom: 1px solid #EEEEEE;
}
main .cart table tbody td:last-child {
	text-align: right;
}
main .cart table .img {
	width: 80px;
}
main .cart table .remove {
	color: #777777;
	font-size: 12px;
	padding-top: 3px;
}
main .cart table .remove:hover {
	text-decoration: underline;
}
main .cart table .price {
	color: #999999;
}
main .cart table a {
	text-decoration: none;
	color: #555555;
}
main .cart table input[type="number"] {
	width: 68px;
	padding: 10px;
	border: 1px solid #ccc;
	color: #555555;
	border-radius: 5px;
}
main .cart .subtotal {
	text-align: right;
	padding: 40px 0;
}
main .cart .subtotal .text {
	padding-right: 40px;
	font-size: 18px;
}
main .cart .subtotal .price {
	font-size: 18px;
	color: #999999;
}
main .cart .buttons {
	text-align: right;
	padding-bottom: 40px;
}
main .cart .buttons input[type="submit"] {
	margin-left: 5px;
	padding: 12px 20px;
	border: 0;
	background: #4e5c70;
	color: #FFFFFF;
	font-size: 14px;
	font-weight: bold;
	cursor: pointer;
	border-radius: 5px;
}
main .cart .buttons input[type="submit"]:hover {
	background: #434f61;
}
main .placeorder h1 {
	display: block;
	font-weight: normal;
	margin: 0;
	padding: 40px 0;
	font-size: 24px;
	text-align: center;
	width: 100%;
}
main .placeorder p {
	text-align: center;
}
footer {
	position: absolute;
	bottom: 0;
	border-top: 1px solid #EEEEEE;
	padding: 20px 0;
	width: 100%;
}

Ce sera la feuille de style que nous utiliserons pour le système de panier.

4. Création du fichier de fonctions

Le fichier functions.php contiendra toutes les fonctions que nous allons utiliser dans notre système de panier d'achat, notamment l'en-tête du modèle, le pied de page du modèle et les fonctions de connexion à la base de données.

Modifiez le fichier functions.php et ajoutez ce qui suit :

PHPCopie
<?php
function pdo_connect_mysql() {
    // Update the details below with your MySQL details
    $DATABASE_HOST = 'localhost';
    $DATABASE_USER = 'root';
    $DATABASE_PASS = '';
    $DATABASE_NAME = 'shoppingcart';
    try {
    	return new PDO('mysql:host=' . $DATABASE_HOST . ';dbname=' . $DATABASE_NAME . ';charset=utf8', $DATABASE_USER, $DATABASE_PASS);
    } catch (PDOException $exception) {
    	// If there is an error with the connection, stop the script and display the error.
    	exit('Failed to connect to database!');
    }
}
// Template header, feel free to customize this
function template_header($title) {
echo <<<EOT
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>$title</title>
		<link href="style.css" rel="stylesheet" type="text/css">
		<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
	</head>
	<body>
        <header>
            <div class="content-wrapper">
                <h1>Shopping Cart System</h1>
                <nav>
                    <a href="index.php">Home</a>
                    <a href="index.php?page=products">Products</a>
                </nav>
                <div class="link-icons">
                    <a href="index.php?page=cart">
						<i class="fas fa-shopping-cart"></i>
					</a>
                </div>
            </div>
        </header>
        <main>
EOT;
}
// Template footer
function template_footer() {
$year = date('Y');
echo <<<EOT
        </main>
        <footer>
            <div class="content-wrapper">
                <p>&copy; $year, Shopping Cart System</p>
            </div>
        </footer>
        <script src="script.js"></script>
    </body>
</html>
EOT;
}
?>

Ces fonctions nous permettront de nous connecter beaucoup plus facilement à la base de données et de formater nos pages. Nous inclurons ce fichier dans la majorité de nos fichiers PHP. Au lieu d'écrire le même code de modèle à plusieurs reprises, nous pouvons facilement exécuter le nom de la fonction. Nous pouvons également modifier la disposition de notre système de panier d'achat sans modifier chaque fichier.

Nous utilisons Font Awesome (bibliothèque d'icônes gratuite) pour nos icônes de polices. La feuille de style CDN est incluse dans la section d'en-tête HTML (fonction d'en-tête de modèle).

5. Création du fichier d'index

Le fichier index.php sera essentiellement notre fichier principal pour accéder à toutes nos pages. Nous allons configurer le routage de base et utiliser les requêtes GET pour déterminer quelle page correspond à quelle page.

5.1. Connectez-vous à la base de données MySQL

Modifiez le fichier index.php et ajoutez ce qui suit :

PHPCopie
<?php
session_start();
// Include functions and connect to the database using PDO MySQL
include 'functions.php';
$pdo = pdo_connect_mysql();

Nous créons d'abord la session avec lesession_startune fonction. Avec cela, nous pouvons stocker les produits qui sont ajoutés au panier, par la suite, le script se connectera à MySQL en utilisant la fonction de connexion à la base de données que nous avons créée précédemment, dans le fichier functions.php .

Remarque : mettez à jour les variables de connexion à la base de données si vous ne pouvez pas vous connecter à MySQL.

5.2. Routage de base

Ajouter après :

PHPCopie
// Page is set to home (home.php) by default, so when the visitor visits that will be the page they see.
$page = isset($_GET['page']) && file_exists($_GET['page'] . '.php') ? $_GET['page'] : 'home';
// Include and show the requested page
include $page . '.php';
?>

La méthode de routage de base utilisée ci-dessus vérifie si la variable de requête GET ($_GET['page']) existe. Sinon, la page par défaut sera définie sur la page d'accueil, alors que si elle existe, ce sera la page demandée.

Par exemple, si nous voulons accéder à la page des produits, nous pouvons accéder à http://localhost/shoppingcart/index.php?page=products .

Si vous accédez à la page index.php dans votre navigateur, la page apparaîtra vide, c'est parce que nous n'avons pas encore modifié le fichier home.php .

6. Création de la page d'accueil

La page d'accueil sera la première page que nos clients verront. Pour cette page, nous pouvons ajouter une image et un texte en vedette, ainsi qu'une liste de 4 produits récemment ajoutés.

6.1. Obtenez 4 produits de la base de données

Modifiez le fichier home.php et ajoutez ce qui suit :

PHPCopie
<?php
// Get the 4 most recently added products
$stmt = $pdo->prepare('SELECT * FROM products ORDER BY date_added DESC LIMIT 4');
$stmt->execute();
$recently_added_products = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

Le code ci-dessus exécutera une requête SQL qui récupérera les quatre produits les plus récemment ajoutés de notre base de données. Tout ce que nous avons à faire avec cette requête est d'ordonner par ledate_addedcolonne et limiter le montant par 4, assez simple non ? Et puis stocker le résultat dans le$recently_added_productsvariable en tant que tableau associé.

6.2. Créer un modèle de maison

Ajoutez après la balise de fermeture PHP :

PHPCopie
<?=template_header('Home')?>

<div class="featured">
    <h2>Gadgets</h2>
    <p>Essential gadgets for everyday use</p>
</div>
<div class="recentlyadded content-wrapper">
    <h2>Recently Added Products</h2>
    <div class="products">
        <?php foreach ($recently_added_products as $product): ?>
        <a href="index.php?page=product&id=<?=$product['id']?>" class="product">
            <img src="imgs/<?=$product['img']?>" width="200" height="200" alt="<?=$product['name']?>">
            <span class="name"><?=$product['name']?></span>
            <span class="price">
                &dollar;<?=$product['price']?>
                <?php if ($product['rrp'] > 0): ?>
                <span class="rrp">&dollar;<?=$product['rrp']?></span>
                <?php endif; ?>
            </span>
        </a>
        <?php endforeach; ?>
    </div>
</div>

<?=template_footer()?>

Cela nous créera un modèle de page d'accueil de base. Le code ci-dessus itérera la variable de tableau $recently_added_products et les remplira en conséquence. Le prix RRP sera inclus mais seulement si la valeur est supérieure à 0.

Si vous préférez utiliser votre propre devise, vous pouvez modifier le$code d'entité. Vous pouvez trouver la liste ici .

Remarque : toutes les images du produit se trouvent dans le répertoire img . Vous devrez télécharger les images de ces produits si vous utilisez les exemples de produits que nous avons créés précédemment. 

Si nous naviguons vers http://localhost/shoppingcart/index.php , cela devrait ressembler à ceci :

http://localhost/shoppingcart/index.php
Page d'accueil du panier

Vous pouvez également accéder à la page d'accueil en spécifiant le paramètre page ( http://localhost/shoppingcart/index.php?page=home ). Cela est possible grâce au routage de base que nous avons implémenté précédemment.

7. Création de la page Produits

La page des produits sera l'endroit où nos clients iront pour parcourir tous nos produits. Nous limiterons le nombre de produits à afficher sur chaque page et ajouterons une pagination qui permettra aux clients de naviguer entre les pages.

7.1. Obtenir des produits de la base de données avec pagination

Modifiez le fichier products.php et ajoutez ce qui suit :

PHPCopie
<?php
// The amounts of products to show on each page
$num_products_on_each_page = 4;
// The current page, in the URL this will appear as index.php?page=products&p=1, index.php?page=products&p=2, etc...
$current_page = isset($_GET['p']) && is_numeric($_GET['p']) ? (int)$_GET['p'] : 1;
// Select products ordered by the date added
$stmt = $pdo->prepare('SELECT * FROM products ORDER BY date_added DESC LIMIT ?,?');
// bindValue will allow us to use integer in the SQL statement, we need to use for LIMIT
$stmt->bindValue(1, ($current_page - 1) * $num_products_on_each_page, PDO::PARAM_INT);
$stmt->bindValue(2, $num_products_on_each_page, PDO::PARAM_INT);
$stmt->execute();
// Fetch the products from the database and return the result as an Array
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);

Mise à jour du$num_products_on_each_pagelimitera le nombre de produits à afficher sur chaque page.

Pour déterminer sur quelle page se trouve le client, nous pouvons utiliser une requête GET, dans l'URL cela apparaîtra comme index.php?page=products&p=1 etc, et dans notre script PHP le paramètre p que nous pouvons récupérer avec le$_GET['p']variable. En supposant que la requête est valide, le code exécutera une requête qui récupérera les produits limités de notre base de données.

Remarque : Nous exécutons des requêtes à l'aide d'instructions préparées. Les instructions préparées empêcheront totalement l' injection SQL . Il est recommandé de préparer des instructions avec des requêtes GET et POST .

7.2. Obtenez le nombre total de produits

Ajouter après :

PHPCopie
// Get the total number of products
$total_products = $pdo->query('SELECT * FROM products')->rowCount();
?>

Le code ci-dessus obtiendra le nombre total de produits dans notre tableau de produits . Le client pourra voir le nombre total de produits en haut de la page des produits.

7.3. Créer un modèle de produits

Ajoutez après la balise de fermeture PHP :

PHPCopie
<?=template_header('Products')?>

<div class="products content-wrapper">
    <h1>Products</h1>
    <p><?=$total_products?> Products</p>
    <div class="products-wrapper">
        <?php foreach ($products as $product): ?>
        <a href="index.php?page=product&id=<?=$product['id']?>" class="product">
            <img src="imgs/<?=$product['img']?>" width="200" height="200" alt="<?=$product['name']?>">
            <span class="name"><?=$product['name']?></span>
            <span class="price">
                &dollar;<?=$product['price']?>
                <?php if ($product['rrp'] > 0): ?>
                <span class="rrp">&dollar;<?=$product['rrp']?></span>
                <?php endif; ?>
            </span>
        </a>
        <?php endforeach; ?>
    </div>
    <div class="buttons">
        <?php if ($current_page > 1): ?>
        <a href="index.php?page=products&p=<?=$current_page-1?>">Prev</a>
        <?php endif; ?>
        <?php if ($total_products > ($current_page * $num_products_on_each_page) - $num_products_on_each_page + count($products)): ?>
        <a href="index.php?page=products&p=<?=$current_page+1?>">Next</a>
        <?php endif; ?>
    </div>
</div>

<?=template_footer()?>

Vous souvenez-vous des produits récemment ajoutés que nous avons créés pour la page d'accueil ? Nous utilisons essentiellement le même code, mais à la place, il est déterminé par la page des produits et le$num_products_on_each_pagevariable.

Les boutons Next et Prev ne seront visibles par l'utilisateur que si le nombre total de produits est supérieur au$num_products_on_each_pagevariable.

Si nous naviguons vers http://localhost/shoppingcart/index.php?page=products, cela devrait ressembler à ceci :

http://localhost/shoppingcart/index.php?page=products
Page des produits du panier d'achat

C'est essentiellement tout ce que nous devons faire pour la page des produits, des fonctionnalités supplémentaires telles que le tri des produits sont disponibles dans les packages avancés.

8. Création de la page produit

La page du produit affichera tous les détails d'un produit spécifié, déterminés par la variable d'ID de requête GET. Les clients peuvent voir le prix, l'image et la description. Le client pourra modifier la quantité et l'ajouter au panier en un clic.

8.1. Obtenir le produit de la base de données avec la requête GET

Modifiez le fichier product.php et ajoutez ce qui suit :

PHPCopie
<?php
// Check to make sure the id parameter is specified in the URL
if (isset($_GET['id'])) {
    // Prepare statement and execute, prevents SQL injection
    $stmt = $pdo->prepare('SELECT * FROM products WHERE id = ?');
    $stmt->execute([$_GET['id']]);
    // Fetch the product from the database and return the result as an Array
    $product = $stmt->fetch(PDO::FETCH_ASSOC);
    // Check if the product exists (array is not empty)
    if (!$product) {
        // Simple error to display if the id for the product doesn't exists (array is empty)
        exit('Product does not exist!');
    }
} else {
    // Simple error to display if the id wasn't specified
    exit('Product does not exist!');
}
?>

Le code ci-dessus vérifiera si le demandéidvariable (requête GET) existe. Si spécifié, le code procédera à la récupération du produit à partir de la table des produits dans notre base de données.

Si le produit n'existe pas dans la base de données, le code affichera une simple erreur, leexit()empêchera l'exécution ultérieure du script et affichera l'erreur.

8.2. Créer un modèle de produit

Ajoutez après la balise de fermeture PHP :

PHPCopie
<?=template_header('Product')?>

<div class="product content-wrapper">
    <img src="imgs/<?=$product['img']?>" width="500" height="500" alt="<?=$product['name']?>">
    <div>
        <h1 class="name"><?=$product['name']?></h1>
        <span class="price">
            &dollar;<?=$product['price']?>
            <?php if ($product['rrp'] > 0): ?>
            <span class="rrp">&dollar;<?=$product['rrp']?></span>
            <?php endif; ?>
        </span>
        <form action="index.php?page=cart" method="post">
            <input type="number" name="quantity" value="1" min="1" max="<?=$product['quantity']?>" placeholder="Quantity" required>
            <input type="hidden" name="product_id" value="<?=$product['id']?>">
            <input type="submit" value="Add To Cart">
        </form>
        <div class="description">
            <?=$product['desc']?>
        </div>
    </div>
</div>

<?=template_footer()?>

Le modèle que nous utiliserons pour la page produit. Le formulaire est créé et l'attribut action est défini sur la page du panier (index.php?page=cart) avec la méthode définie sur post. La page du panier (cart.php) ajoutera le produit au panier.

Avec le champ du formulaire de quantité, on peut fixer une valeur maximale, cette valeur est fixée à la quantité du produit (récupérée de la table des produits). L'identifiant du produit est également ajouté au formulaire, car c'est ainsi que nous savons quel produit le client a ajouté.

Nous n'avons pas besoin d'inclure le nom, la description, etc. du produit, car nous pouvons obtenir ces données à partir de la table des produits dans notre base de données avec l'ID du produit.

Si nous naviguons vers http://localhost/shoppingcart/index.php?page=product&id=1 , cela devrait ressembler à ceci :

http://localhost/shoppingcart/index.php?page=product&id=1
Panier d'achat Page produit

Si vous changez le idparamètre dans l'URL disons 2, cela nous montrera un produit différent.

9. Création de la page du panier

La page du panier est l'endroit où le client pourra voir une liste de ses produits ajoutés au panier. Ils auront la possibilité de supprimer des produits et de mettre à jour les quantités.

9.1. Ajouter un produit au panier

Modifiez le fichier cart.php et ajoutez ce qui suit :

PHPCopie
<?php
// If the user clicked the add to cart button on the product page we can check for the form data
if (isset($_POST['product_id'], $_POST['quantity']) && is_numeric($_POST['product_id']) && is_numeric($_POST['quantity'])) {
    // Set the post variables so we easily identify them, also make sure they are integer
    $product_id = (int)$_POST['product_id'];
    $quantity = (int)$_POST['quantity'];
    // Prepare the SQL statement, we basically are checking if the product exists in our databaser
    $stmt = $pdo->prepare('SELECT * FROM products WHERE id = ?');
    $stmt->execute([$_POST['product_id']]);
    // Fetch the product from the database and return the result as an Array
    $product = $stmt->fetch(PDO::FETCH_ASSOC);
    // Check if the product exists (array is not empty)
    if ($product && $quantity > 0) {
        // Product exists in database, now we can create/update the session variable for the cart
        if (isset($_SESSION['cart']) && is_array($_SESSION['cart'])) {
            if (array_key_exists($product_id, $_SESSION['cart'])) {
                // Product exists in cart so just update the quanity
                $_SESSION['cart'][$product_id] += $quantity;
            } else {
                // Product is not in cart so add it
                $_SESSION['cart'][$product_id] = $quantity;
            }
        } else {
            // There are no products in cart, this will add the first product to cart
            $_SESSION['cart'] = array($product_id => $quantity);
        }
    }
    // Prevent form resubmission...
    header('location: index.php?page=cart');
    exit;
}

Dans le code ci-dessus, nous utilisons les variables de session PHP . Nous pouvons utiliser des sessions PHP pour mémoriser les produits du panier, par exemple, lorsqu'un client navigue vers une autre page, etc., le panier contiendra toujours les produits précédemment ajoutés jusqu'à l'expiration de la session.

Le code ci-dessus vérifiera si un produit a été ajouté au panier. Si vous revenez au fichier product.php , vous pouvez voir que nous avons créé un formulaire HTML. Nous vérifions ces valeurs de formulaire, si le produit existe, procédez à la vérification du produit en le sélectionnant dans notre table de produits dans notre base de données. Nous ne voudrions pas que les clients manipulent le système et ajoutent des produits inexistants.

La variable de sessioncartsera un tableau de produits associé, et avec ce tableau, nous pouvons ajouter plusieurs produits au panier. La clé du tableau sera l'ID du produit et la valeur sera la quantité. Si un produit existe déjà dans le panier, il suffit de mettre à jour la quantité.

9.2. Retirer un produit du panier

Ajouter après :

PHPCopie
// Remove product from cart, check for the URL param "remove", this is the product id, make sure it's a number and check if it's in the cart
if (isset($_GET['remove']) && is_numeric($_GET['remove']) && isset($_SESSION['cart']) && isset($_SESSION['cart'][$_GET['remove']])) {
    // Remove the product from the shopping cart
    unset($_SESSION['cart'][$_GET['remove']]);
}

Sur la page du panier, le client aura la possibilité de supprimer un produit du panier. Lorsque le bouton est cliqué, nous pouvons utiliser une requête GET pour déterminer quel produit supprimer, par exemple, si nous avons un produit avec l'ID 1, l'URL suivante le supprimera du panier : http://localhost/shoppingcart /index.php?page=cart&remove=1 .

9.3. Mise à jour des quantités de produits

Ajouter après :

PHPCopie
// Update product quantities in cart if the user clicks the "Update" button on the shopping cart page
if (isset($_POST['update']) && isset($_SESSION['cart'])) {
    // Loop through the post data so we can update the quantities for every product in cart
    foreach ($_POST as $k => $v) {
        if (strpos($k, 'quantity') !== false && is_numeric($v)) {
            $id = str_replace('quantity-', '', $k);
            $quantity = (int)$v;
            // Always do checks and validation
            if (is_numeric($id) && isset($_SESSION['cart'][$id]) && $quantity > 0) {
                // Update new quantity
                $_SESSION['cart'][$id] = $quantity;
            }
        }
    }
    // Prevent form resubmission...
    header('location: index.php?page=cart');
    exit;
}

Le code ci-dessus itérera les produits dans le panier et mettra à jour les quantités. Le client aura la possibilité de modifier les quantités sur la page du panier. Le bouton Mettre à jour porte le nom de mise à jour , car c'est ainsi que le code saura quand mettre à jour les quantités à l'aide d'une requête POST.

9.4. Traitement de la commande

Ajouter après :

PHPCopie
// Send the user to the place order page if they click the Place Order button, also the cart should not be empty
if (isset($_POST['placeorder']) && isset($_SESSION['cart']) && !empty($_SESSION['cart'])) {
    header('Location: index.php?page=placeorder');
    exit;
}

Cela redirigera l'utilisateur vers la page de commande s'il clique sur le bouton Passer la commande .

9.5. Obtenir des produits dans le panier et sélectionner dans la base de données

Ajouter après :

PHPCopie
// Check the session variable for products in cart
$products_in_cart = isset($_SESSION['cart']) ? $_SESSION['cart'] : array();
$products = array();
$subtotal = 0.00;
// If there are products in cart
if ($products_in_cart) {
    // There are products in the cart so we need to select those products from the database
    // Products in cart array to question mark string array, we need the SQL statement to include IN (?,?,?,...etc)
    $array_to_question_marks = implode(',', array_fill(0, count($products_in_cart), '?'));
    $stmt = $pdo->prepare('SELECT * FROM products WHERE id IN (' . $array_to_question_marks . ')');
    // We only need the array keys, not the values, the keys are the id's of the products
    $stmt->execute(array_keys($products_in_cart));
    // Fetch the products from the database and return the result as an Array
    $products = $stmt->fetchAll(PDO::FETCH_ASSOC);
    // Calculate the subtotal
    foreach ($products as $product) {
        $subtotal += (float)$product['price'] * (int)$products_in_cart[$product['id']];
    }
}
?>

S'il y a des produits dans le panier, récupérez ces produits dans notre table de produits , ainsi que le nom de colonne suivant : nom du produit, description, image et prix, car auparavant, nous ne stockions pas ces informations dans notre variable de session.

Nous calculons également le sous-total en itérant les produits et en multipliant le prix par la quantité.

9.6. Créer un modèle de panier

Ajoutez ci-dessous la balise de fermeture PHP :

PHPCopie
<?=template_header('Cart')?>

<div class="cart content-wrapper">
    <h1>Shopping Cart</h1>
    <form action="index.php?page=cart" method="post">
        <table>
            <thead>
                <tr>
                    <td colspan="2">Product</td>
                    <td>Price</td>
                    <td>Quantity</td>
                    <td>Total</td>
                </tr>
            </thead>
            <tbody>
                <?php if (empty($products)): ?>
                <tr>
                    <td colspan="5" style="text-align:center;">You have no products added in your Shopping Cart</td>
                </tr>
                <?php else: ?>
                <?php foreach ($products as $product): ?>
                <tr>
                    <td class="img">
                        <a href="index.php?page=product&id=<?=$product['id']?>">
                            <img src="imgs/<?=$product['img']?>" width="50" height="50" alt="<?=$product['name']?>">
                        </a>
                    </td>
                    <td>
                        <a href="index.php?page=product&id=<?=$product['id']?>"><?=$product['name']?></a>
                        <br>
                        <a href="index.php?page=cart&remove=<?=$product['id']?>" class="remove">Remove</a>
                    </td>
                    <td class="price">&dollar;<?=$product['price']?></td>
                    <td class="quantity">
                        <input type="number" name="quantity-<?=$product['id']?>" value="<?=$products_in_cart[$product['id']]?>" min="1" max="<?=$product['quantity']?>" placeholder="Quantity" required>
                    </td>
                    <td class="price">&dollar;<?=$product['price'] * $products_in_cart[$product['id']]?></td>
                </tr>
                <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>
        <div class="subtotal">
            <span class="text">Subtotal</span>
            <span class="price">&dollar;<?=$subtotal?></span>
        </div>
        <div class="buttons">
            <input type="submit" value="Update" name="update">
            <input type="submit" value="Place Order" name="placeorder">
        </div>
    </form>
</div>

<?=template_footer()?>

C'est tout ce que nous devons faire pour la page du panier. Le client peut désormais supprimer des produits et mettre à jour les quantités.

Si vous ajoutez quelques produits au panier et accédez à http://localhost/shoppingcart/index.php?page=cart , il ressemblera à ce qui suit :

http://localhost/shoppingcart/index.php?page=cart
Panier

Pour obtenir la quantité à afficher dans l'en-tête, vous devrez modifier le fichier functions.php et ajouter ce qui suit à la fonction d'en-tête du modèle :

PHPCopie
// Get the amount of items in the shopping cart, this will be displayed in the header.
$num_items_in_cart = isset($_SESSION['cart']) ? count($_SESSION['cart']) : 0;

Trouver:

<i class="fas fa-shopping-cart"></i>

Ajouter après :

PHPCopie
<span>$num_items_in_cart</span>

Et maintenant, le client saura à tout moment combien de produits il a dans son panier, car cela apparaîtra sur chaque page.

Produit dans le panier

10. Création de la page de commande

Cette page permettra au client de savoir qu'il a passé une commande. Le client doit avoir des produits dans son panier et avoir cliqué sur le bouton Passer une commande sur la page du panier.

10.1. Création du modèle de commande de place

Modifiez le fichier placeorder.php et ajoutez ce qui suit :

PHPCopie
<?=template_header('Place Order')?>

<div class="placeorder content-wrapper">
    <h1>Your Order Has Been Placed</h1>
    <p>Thank you for ordering with us, we'll contact you by email with your order details.</p>
</div>

<?=template_footer()?>

Et maintenant, si nous ajoutons un produit à notre panier et cliquons sur le bouton Passer la commande , nous verrons ce qui suit :

http://localhost/index.php?page=placeorder
Panier Passer une commande

N'hésitez pas à modifier le message de commande, etc.

Conclusion

Toutes nos félicitations! Vous avez créé avec succès un système de panier d'achat avec PHP et MySQL, et ensuite ? Envisagez d'ajouter une page de paiement et d'intégrer un mode de paiement, tel que PayPal. PayPal fournit sa propre API pour les développeurs . 

N'oubliez pas qu'il ne s'agit que d'un système de panier d'achat de base à partir duquel vous pouvez travailler. Par conséquent, je ne recommande pas de passer en production tant que vous n'avez pas apporté un nombre raisonnable de modifications et d'ajouts. Vous devrez ajouter votre propre gestion des erreurs, votre mode de paiement et validation.

Si vous avez apprécié ce didacticiel, n'oubliez pas d'appuyer sur le bouton de partage et de laisser un commentaire, cela nous aidera à créer plus de contenu futur.

Enregistrer un commentaire

Post a Comment (0)

Plus récente Plus ancienne