By GokiSoft.com|
20:27 09/03/2022|
Học PHP
[Video] Bài tập - Xây dựng cart (giỏ hàng) + checkout (thanh toán) sử dụng Cookie & localStorage - Lập trình PHP/MySQL - C2108L
#db/config.php
<?php
define('HOST', 'localhost');
define('DATABASE', 'BT2290');
define('USERNAME', 'root');
define('PASSWORD', '');
const SQL_CREATE_DATABASE = 'create database IF NOT EXISTS '.DATABASE;
const SQL_CREATE_TABLE_PRODUCTS = 'create table IF NOT EXISTS products (
id int primary key auto_increment,
title varchar(150) not null,
price float,
thumbnail varchar(500),
content text,
created_at datetime,
updated_at datetime
)';
const SQL_CREATE_TABLE_ORDERS = 'create table IF NOT EXISTS orders (
id int primary key auto_increment,
fullname varchar(50),
phone_number varchar(20),
email varchar(150),
address varchar(200),
order_date datetime
)';
const SQL_CREATE_TABLE_ORDER_DETAIL = 'create table IF NOT EXISTS order_detail (
id int primary key auto_increment,
order_id int references orders (id),
product_id int references products (id),
num int,
price float
)';
#db/dbhelper.php
<?php
require_once('config.php');
//create database
function initDB() {
// Mo ket noi toi CSDL
$conn = mysqli_connect(HOST, USERNAME, PASSWORD);
mysqli_set_charset($conn, 'utf8');
// Thuc hien query -> insert du lieu vao database
// $query = "insert into Users(fullname, email, password, address) values ('$fullname', '$email', '$pwd', '$address')";
// echo $query;
mysqli_query($conn, SQL_CREATE_DATABASE);
// Dong ket noi CSDL
mysqli_close($conn);
}
/**
* Ham nay se su dung cho TH cau truy van: insert, update, delete
*/
function execute($query) {
// Mo ket noi toi CSDL
$conn = mysqli_connect(HOST, USERNAME, PASSWORD, DATABASE);
mysqli_set_charset($conn, 'utf8');
// Thuc hien query -> insert du lieu vao database
// $query = "insert into Users(fullname, email, password, address) values ('$fullname', '$email', '$pwd', '$address')";
// echo $query;
mysqli_query($conn, $query);
// Dong ket noi CSDL
mysqli_close($conn);
}
function executeResult($query, $isSingle = false) {
// Mo ket noi toi CSDL
$conn = mysqli_connect(HOST, USERNAME, PASSWORD, DATABASE);
mysqli_set_charset($conn, 'utf8');
// Thuc hien query -> insert du lieu vao database
// $query = "insert into Users(fullname, email, password, address) values ('$fullname', '$email', '$pwd', '$address')";
// echo $query;
// $query = "select * from Users where email = '$email' and password = '$pwd'";
$resultset = mysqli_query($conn, $query);
if($isSingle) {
$data = mysqli_fetch_array($resultset, 1);
} else {
$data = [];
while(($row = mysqli_fetch_array($resultset, 1)) != null) {
$data[] = $row;
}
}
// Dong ket noi CSDL
mysqli_close($conn);
return $data;
}
#utils/utility.php
<?php
function getPost($key, $slash = '\'') {
$value = '';
if(isset($_POST[$key])) {
$value = $_POST[$key];
// $value = Sinh Vien ' ABC ' => Sinh Vien \' ABC \'
// \\ -> \
// \' -> '
// \' (Hieu la: ') -> \\\' (Hieu la: \')
$value = str_replace($slash, "\\".$slash, $value);
}
return $value;
}
function getGet($key, $slash = '\'') {
$value = '';
if(isset($_GET[$key])) {
$value = $_GET[$key];
$value = str_replace($slash, "\\".$slash, $value);
}
return $value;
}
#cart.php
<?php
session_start();
require_once('utils/utility.php');
require_once('db/dbhelper.php');
if(!isset($_SESSION['cart'])) {
$_SESSION['cart'] = [];
}
if(!empty($_POST)) {
$id = getPost('id');
for ($i=0; $i < count($_SESSION['cart']); $i++) {
if($_SESSION['cart'][$i]['id'] == $id) {
array_splice($_SESSION['cart'], $i, 1);
break;
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Init Database</title>
<!-- Bootstrap -> thiet ke GUI -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style type="text/css">
.form-group {
margin-bottom: 20px;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-sm bg-light navbar-light">
<div class="container-fluid">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="products.php">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="init.php">Init DB</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">Cart</a>
</li>
<li class="nav-item">
<a class="nav-link" href="checkout.php">Checkout</a>
</li>
</ul>
</div>
</nav>
<div class="container" style="padding: 20px;">
<div class="row">
<table class="table table-bordered">
<thead>
<tr>
<th>No</th>
<th>Thumbnail</th>
<th>Title</th>
<th>Price</th>
<th>Num</th>
<th>Total</th>
<th style="width: 60px"></th>
</tr>
</thead>
<tbody>
<?php
$index = 0;
foreach($_SESSION['cart'] as $item) {
echo '<tr>
<td>'.(++$index).'</td>
<td><img src="'.$item['thumbnail'].'" style="width: 200px"/></td>
<td>'.$item['title'].'</td>
<td>'.$item['price'].'</td>
<td>
<input type="number" min="0" max="100" value="'.$item['num'].'" class="form-control" style="width: 80px"/>
</td>
<td>
'.($item['price'] * $item['num']).'
</td>
<td>
<form method="post">
<input type="number" name="id" value="'.$item['id'].'" class="form-control" style="width: 200px; display: none;">
<button class="btn btn-danger">Delete</button>
</form>
</td>
</tr>';
}
?>
</tbody>
</table>
<a href="checkout.php"><button class="btn btn-warning">Checkout</button></a>
</div>
</div>
</body>
</html>
#checkout.php
<?php
session_start();
require_once('utils/utility.php');
require_once('db/dbhelper.php');
if(!isset($_SESSION['cart'])) {
$_SESSION['cart'] = [];
}
if(!empty($_POST) && isset($_SESSION['cart']) && count($_SESSION['cart']) > 0) {
$fullname = getPost('fullname');
$email = getPost('email');
$phoneNumber = getPost('phone_number');
$address = getPost('address');
$order_date = date('Y-m-d H:i:s');
$sql = "insert into orders(fullname, email, phone_number, address, order_date) values ('$fullname', '$email', '$phoneNumber', '$address', '$order_date')";
execute($sql);
$sql = "select * from orders where order_date = '$order_date'";
$orderItem = executeResult($sql, true);
$orderId = $orderItem['id'];
foreach($_SESSION['cart'] as $item) {
$product_id = $item['id'];
$num = $item['num'];
$price = $item['price'];
$sql = "insert into order_detail(order_id, product_id, num, price) values ($orderId, '$product_id', '$num', '$price')";
execute($sql);
}
unset($_SESSION['cart']);
header('Location: complete.php');
die();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Init Database</title>
<!-- Bootstrap -> thiet ke GUI -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style type="text/css">
.form-group {
margin-bottom: 20px;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-sm bg-light navbar-light">
<div class="container-fluid">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="products.php">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="init.php">Init DB</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">Cart</a>
</li>
<li class="nav-item">
<a class="nav-link" href="checkout.php">Checkout</a>
</li>
</ul>
</div>
</nav>
<div class="container" style="padding: 20px;">
<div class="row">
<table class="table table-bordered">
<thead>
<tr>
<th>No</th>
<th>Thumbnail</th>
<th>Title</th>
<th>Price</th>
<th>Num</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<?php
$index = 0;
foreach($_SESSION['cart'] as $item) {
echo '<tr>
<td>'.(++$index).'</td>
<td><img src="'.$item['thumbnail'].'" style="width: 200px"/></td>
<td>'.$item['title'].'</td>
<td>'.$item['price'].'</td>
<td>'.$item['num'].'</td>
<td>'.($item['price'] * $item['num']).'</td>
</tr>';
}
?>
</tbody>
</table>
<form method="post">
<div class="form-group">
<label>Fullname: </label>
<input required type="text" name="fullname" class="form-control">
</div>
<div class="form-group">
<label>Email: </label>
<input required type="email" name="email" class="form-control">
</div>
<div class="form-group">
<label>Phone Number: </label>
<input required type="tel" name="phone_number" class="form-control">
</div>
<div class="form-group">
<label>Address: </label>
<input required type="text" name="address" class="form-control">
</div>
<div class="form-group">
<button class="btn btn-success">Checkout Complete</button>
</div>
</form>
</div>
</div>
</body>
</html>
#complete.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Complete Page</title>
<!-- Bootstrap -> thiet ke GUI -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style type="text/css">
.form-group {
margin-bottom: 20px;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-sm bg-light navbar-light">
<div class="container-fluid">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="products.php">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="init.php">Init DB</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">Cart</a>
</li>
<li class="nav-item">
<a class="nav-link" href="checkout.php">Checkout</a>
</li>
</ul>
</div>
</nav>
<h1 style="text-align: center;">Checkout Complete</h1>
</body>
</html>
#details.php
<?php
session_start();
require_once('utils/utility.php');
require_once('db/dbhelper.php');
$id = getGet('id');
$sql = "select * from products where id = '$id'";
$product = executeResult($sql, true);
if($product == null) {
header('Location: error.php');
die();
}
if(!empty($_POST)) {
$num = getPost('num');
if(!isset($_SESSION['cart'])) {
$_SESSION['cart'] = [];
}
$isFind = false;
for ($i=0; $i < count($_SESSION['cart']); $i++) {
if($_SESSION['cart'][$i]['id'] == $id) {
$_SESSION['cart'][$i]['num'] += $num;
$isFind = true;
break;
}
}
if(!$isFind) {
$_SESSION['cart'][] = [
'id' => $id,
'title' => $product['title'],
'thumbnail' => $product['thumbnail'],
'price' => $product['price'],
'num'=> $num
];
}
// var_dump($_SESSION['cart']);
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Init Database</title>
<!-- Bootstrap -> thiet ke GUI -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style type="text/css">
.form-group {
margin-bottom: 20px;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-sm bg-light navbar-light">
<div class="container-fluid">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="products.php">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="init.php">Init DB</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">Cart</a>
</li>
<li class="nav-item">
<a class="nav-link" href="checkout.php">Checkout</a>
</li>
</ul>
</div>
</nav>
<div class="container" style="padding: 20px;">
<div class="row">
<div class="col-md-5">
<img src="<?=$product['thumbnail']?>" style="width: 100%;">
</div>
<div class="col-md-7">
<h3><?=$product['title']?></h3>
<p style="font-size: 20px; color: red">
<?=$product['price']?> VND
</p>
<form method="post">
<p>
<input type="number" name="id" value="<?=$id?>" class="form-control" style="width: 200px; display: none;">
<input required type="number" min="1" max="100" name="num" value="1" class="form-control" style="width: 200px">
</p>
<button class="btn btn-success" style="width: 200px">Add to cart</button>
</form>
</div>
</div>
</div>
</body>
</html>
#error.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Error Page</title>
</head>
<body>
<nav class="navbar navbar-expand-sm bg-light navbar-light">
<div class="container-fluid">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="products.php">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="init.php">Init DB</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">Cart</a>
</li>
<li class="nav-item">
<a class="nav-link" href="checkout.php">Checkout</a>
</li>
</ul>
</div>
</nav>
<h1 style="text-align: center;">Error</h1>
</body>
</html>
#init.php
<?php
session_start();
if(!empty($_POST)) {
require_once('utils/utility.php');
require_once('db/dbhelper.php');
$action = getPost('action');
if($action == 'init') {
initDB();
execute(SQL_CREATE_TABLE_PRODUCTS);
execute(SQL_CREATE_TABLE_ORDERS);
execute(SQL_CREATE_TABLE_ORDER_DETAIL);
// fake data
// for ($i=0; $i < 20; $i++) {
// $title = 'San pham '.$i;
// $price = 1000 + 10*$i;
// $thumbnail = 'https://gokisoft.com/uploads/stores/49/2021/10/coding-c-program.jpg';
// $content = 'Noi dung '.$i;
// $createdAt = date('Y-m-d H:i:s');
// $updatedAt = date('Y-m-d H:i:s');
// $sql = "insert into products(title, price, thumbnail, content, created_at, updated_at) values ('$title', '$price', '$thumbnail', '$content', '$createdAt', '$updatedAt')";
// execute($sql);
// }
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Init Database</title>
<!-- Bootstrap -> thiet ke GUI -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style type="text/css">
.form-group {
margin-bottom: 20px;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-sm bg-light navbar-light">
<div class="container-fluid">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="products.php">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="init.php">Init DB</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">Cart</a>
</li>
<li class="nav-item">
<a class="nav-link" href="checkout.php">Checkout</a>
</li>
</ul>
</div>
</nav>
<h1 style="text-align: center;">
Init Database
<br/>
<form method="post">
<button class="btn btn-warning" name="action" value="init">Start Init Database</button>
</form>
</h1>
</body>
</html>
#products.php
<?php
session_start();
require_once('utils/utility.php');
require_once('db/dbhelper.php');
$sql = 'select * from products';
$dataList = executeResult($sql);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Init Database</title>
<!-- Bootstrap -> thiet ke GUI -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style type="text/css">
.form-group {
margin-bottom: 20px;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-sm bg-light navbar-light">
<div class="container-fluid">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="products.php">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="init.php">Init DB</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">Cart</a>
</li>
<li class="nav-item">
<a class="nav-link" href="checkout.php">Checkout</a>
</li>
</ul>
</div>
</nav>
<div class="container" style="padding: 20px;">
<div class="row">
<?php
foreach($dataList as $item) {
echo '<div class="col-md-3">
<a href="details.php?id='.$item['id'].'"><img src="'.$item['thumbnail'].'" style="width: 100%">
<p>'.$item['title'].'</p>
<p style="color: red">'.$item['price'].' VND</p>
</a>
</div>';
}
?>
</div>
</div>
</body>
</html>
#readme.txt
Các bước phát triển dự án
B1) Phân tích database
- Tạo database: BT2290
create database BT2290
- Tạo tables
create table products (
id int primary key auto_increment,
title varchar(150) not null,
price float,
thumbnail varchar(500),
content text,
created_at datetime,
updated_at datetime
)
create table orders (
id int primary key auto_increment,
fullname varchar(50),
phone_number varchar(20),
email varchar(150),
address varchar(200),
order_date date
)
create table order_detail (
id int primary key auto_increment,
order_id int references orders (id),
product_id int references products (id),
num int,
price float
)
B2) Xay dung cau truc du an
db
- config.php -> cau hinh csdl
- dbhelper.php -> ham su dung csdl
utils
- utility.php -> function tien ich su dung trong du -> getGet, getPost, ...
init.php
products.php
details.php
cart.php
checkout.php
B3) Giai phap ve quan ly don hang:
- Su dung session:
$_SESSION['cart'] = [
[
'id' => 1,
'title' => '',
'thumbnail' => '',
'price' => 1,
'num': 0
], [
'id' => 1,
'title' => '',
'thumbnail' => '',
'price' => 1,
'num': 0
]
];
Tags:
Phản hồi từ học viên
5
(Dựa trên đánh giá ngày hôm nay)