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
Xây dựng CSDL đặt tên là BT2290 gồm các bảng sau
- products gồm các column: id tự tăng, tiêu đề, thumbnail, nội dung, ngày tạo, ngày sửa
- orders: gồm các column: id tự tăng, tên khách hàng, sđt, email, địa chỉ, ngày tạo đơn hàng
- order_details: gôm các column: id tự tăng, id đơn hàng, id sản phẩm, số lượng, giá tiền
Yêu cầu:
- Fake 25 sản phẩm bằng bất kỳ cách nào bạn biết
- Tạo các page sau:
1) products.php -> Hiển thị danh sách sản phẩm
2) details.php -> Hiển thị chi tiết sản phẩm -> có chưa button add cart
3) cart.php -> chứa danh sách sản phẩm trong giỏ hàng
4) checkout.php -> trang thanh toán -> Khi thực hiện thanh toán thành công -> yêu cầu add thông tin vào 2 bảng orders và order_details
Chú ý: Tham khảo bất kỳ trang bán hàng để thiết kế giao diện.
Tags:
Phản hồi từ học viên
5
(Dựa trên đánh giá ngày hôm nay)
![Do Trung Duc [T2008A]](https://www.gravatar.com/avatar/2973ac07124f066b4605c535e8d39a99.jpg?s=80&d=mm&r=g)
Do Trung Duc
2021-06-14 04:02:38
<?php
require_once ('config.php');
/**
* Su dung voi cau lenh query: insert, update, delete -> ko tra ve ket qua.
*/
function execute($sql) {
//Mo ket noi toi database
$conn = mysqli_connect(HOST, USERNAME, PASSWORD, DATABASE);
mysqli_set_charset($conn, 'utf8');
//Xu ly cau query
mysqli_query($conn, $sql);
//Dong ket noi database
mysqli_close($conn);
}
/**
* Su dung voi cau lenh query: select.
*/
function executeResult($sql) {
//Mo ket noi toi database
$conn = mysqli_connect(HOST, USERNAME, PASSWORD, DATABASE);
mysqli_set_charset($conn, 'utf8');
// echo $sql;
//Xu ly cau query
$resultset = mysqli_query($conn, $sql);
// var_dump($resultset);
// die();
$data = [];
while (($row = mysqli_fetch_array($resultset, 1)) != null) {
$data[] = $row;
}
/**
* TH: param2 = 1
* $row = [
* 'id' => 1,
* 'title' => '1 - Android Tivi Sony 4K 55 inch KD-55X8000H',
* 'thumbnail' => '12321',
* ...
* ];
*
* TH: param2 = 2
* $row = [1, '1 - Android Tivi Sony 4K 55 inch KD-55X8000H', '12321', ...];
*/
//Dong ket noi database
mysqli_close($conn);
return $data;
}
![Do Trung Duc [T2008A]](https://www.gravatar.com/avatar/2973ac07124f066b4605c535e8d39a99.jpg?s=80&d=mm&r=g)
Do Trung Duc
2021-06-14 04:02:07
<?php
require_once('../Library/dbhelper.php');
require_once('../Library/utility.php');
if (!empty($_POST)) {
$fullname = $_POST['fullname'];
$phone = $_POST['phone'];
$email = $_POST['email'];
$address = $_POST['address'];
$created_at = date("Y-m-d H:i:s");
$sql = "insert into orders (fullname, phone, email,address, created_at) values ('$fullname','$phone','$email','address','$created_at')";
execute($sql);
$sql = "select * from orders where created_at = '$created_at'";
$order = executeResult($sql);
$orderId = $order[0]['id'];
//up du lieu vao bang database orderdetail
$cart = [];
if (isset($_COOKIE['cart'])) {
$json = $_COOKIE['cart'];
$cart = json_decode($json,true);
}
$idList = [];
foreach ($cart as $item) {
$idList[] = $item['id'];
}
if (count($idList) > 0) {
$idList = implode(',', $idList);
$sql = "select * from products where id in ($idList)";
$cartData = executeResult($sql);
}
foreach ($cartData as $item) {
$quantity = 0;
foreach ($cart as $product) {
if ($item['id'] == $product['id']) {
$quantity = $product['quantity'];
}
}
// $sql = "insert into orderdetails (orderId, productId, price, quantity) values ('$orderId',".$item['id'].",".$item['price']."$quantity)";
$sql = "insert into orderdetails (orderId, productId, price, quantity) values ('$orderId','".$item['id']."','".$item['price']."', '$quantity')";
execute($sql);
}
setcookie("cart",'[]', time()-10000);
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Ban da dat hang thanh cong</title>
</head>
<body>
Ban da dat hang thanh cong
</body>
</html>
![Do Trung Duc [T2008A]](https://www.gravatar.com/avatar/2973ac07124f066b4605c535e8d39a99.jpg?s=80&d=mm&r=g)
Do Trung Duc
2021-06-14 04:01:55
<?php
require_once('../Library/dbhelper.php');
require_once('../Library/utility.php');
if (!empty($_POST)) {
$id = $_POST['id'];
$quantity = $_POST['quantity'];
}
// var_dump($_POST);
$cart = [];
if (isset($_COOKIE['cart'])) {
$json = $_COOKIE['cart'];
$cart = json_decode($json,true);
}
$exits = false;
// foreach ($cart as $product) {
// if ($product['id'] == $id) {
// $product['quantity'] = 99;
// $exits = true;
// break;
// }
// }
for($i = 0; $i < count($cart); $i++){
if ($cart[$i]['id'] == $id) {
$cart[$i]['quantity'] += $quantity;
$exits = true;
break;
}
}
if ($exits == false) {
$cart[] = [
'id' => $id,
'quantity' => 1
];
}
setcookie("cart",json_encode($cart), time()+3600*24*7);
var_dump($cart);
?>
![Do Trung Duc [T2008A]](https://www.gravatar.com/avatar/2973ac07124f066b4605c535e8d39a99.jpg?s=80&d=mm&r=g)
Do Trung Duc
2021-06-14 04:01:43
<?php
require_once('../Library/dbhelper.php');
require_once('../Library/utility.php');
if (isset($_COOKIE['cart'])) {
$string = $_COOKIE['cart'];
$cart = json_decode($string,true);
}
$idList = [];
foreach ($cart as $item) {
$idList[] = $item['id'];
}
if (count($idList) > 0) {
$idList = implode(',', $idList);
$sql = "select * from products where id in ($idList)";
$cartData = executeResult($sql);
}else{
$cartData = [];
}
?>
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://use.fontawesome.com/425d03015a.js"></script>
</head>
<body>
<div class="row">
<div class="col-md-4" style="box-sizing: border-box;">
<div class="card">
<div class="card-header bg-primary">THONG TIN</div>
<div class="card-body">
<form method="post" action="upcarttoDB.php">
<div class="form-group">
<label for="fullname">Ho ten:</label>
<input name="fullname" type="fullname" class="form-control" placeholder="Enter fullname" required>
</div>
<div class="form-group">
<label for="phone">So Dien thoai:</label>
<input name="phone" type="phone" class="form-control" placeholder="Enter phone" required>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input name="email" type="email" class="form-control" placeholder="Enter email" required>
</div>
<div class="form-group">
<label for="address">Dia chi:</label>
<input name="address" type="address" class="form-control" placeholder="Enter address" required>
</div>
<button type="submit" class="btn btn-primary">Dat Hang</button>
</form>
</div>
</div>
</div>
<div class="col-md-8" style="box-sizing: border-box;">
<div class="container">
<h2>GIO HANG</h2>
<table class="table table-striped">
<thead>
<tr>
<th>STT</th>
<th>TEN SAN PHAM</th>
<th>GIA TIEN</th>
<th>SO LUONG</th>
<th>TONG TIEN</th>
</tr>
</thead>
<tbody>
<?php
$counter = 0;
$bill = 0;
foreach ($cartData as $item) {
$quantity = 0;
foreach ($cart as $product) {
if ($item['id'] == $product['id']) {
$quantity = $product['quantity'];
}
}
$totalMoney = $quantity * $item['price'];
echo '
<tr>
<td>'.++$counter.'</td>
<td>'.$item['title'].'</td>
<td>'.number_format($item['price'], 0, '.', '.').'đ</td>
<td>'.$quantity.'</td>
<td>'.number_format($totalMoney,0,'.','.').'đ</td>
<td><button onclick = "deleteFromCart('.$item['id'].')" class = "btn btn-danger">Xoa</button></td>
</tr>
';
$bill += $totalMoney;
}
?>
</tbody>
</table>
<div>Tong Hoa Don: <?=$bill?> dong</div>
</div>
</div>
</div>
<script type="text/javascript">
function deleteFromCart(id){
$.post("deletefromcart.php",
{'id': id},
function(data){
location.reload();
})
}
</script>
</body>
</html>
![Do Trung Duc [T2008A]](https://www.gravatar.com/avatar/2973ac07124f066b4605c535e8d39a99.jpg?s=80&d=mm&r=g)
Do Trung Duc
2021-06-14 04:01:30
<?php
require_once('../Library/dbhelper.php');
require_once('../Library/utility.php');
$sql = "select * from products";
$productList = executeResult($sql);
?>
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://use.fontawesome.com/425d03015a.js"></script>
</head>
<body>
<div class="container">
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<!-- Brand/logo -->
<a class="navbar-brand" href="#">Logo</a>
<!-- Links -->
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="#">Link 1</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link 2</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link 3</a>
</li>
</ul>
<button onclick="window.open('cart.php')" style="position: absolute; right: 10px;," type="button" class="btn btn-warning"><i class="fa fa-shopping-cart"></i></button>
</nav>
<div class="products row" style="text-align: center;">
<?php
foreach ($productList as $product) {
// $english_format_number = number_format($number, 2, '.', '');
echo '
<div class="col-md-2">
<img style="width: 100%" src="'.$product['thumnail'].'">
<p>'.$product['title'].'</p>
<p>'.number_format($product['price'], 0, '.', '.').'đ</p>
<p>'.$product['content'].'</p>
<p><button onclick = "addToCart('.$product['id'].')" type="button" class="btn btn-warning">Thêm vào giỏ</button></p>
</div>
';
}
?>
</div>
</div>
<!-- content -->
</body>
<script type="text/javascript">
function addToCart(id) {
console.log(id);
$.post("addtocard.php",
{'id': id, 'quantity': 1},
function(data){
location.reload();
alert(data);
})
}
</script>
</html>
![Đào Mạnh Dũng [C2010L]](https://www.gravatar.com/avatar/6a111fa53fd75dc87034660a8857df16.jpg?s=80&d=mm&r=g)
Đào Mạnh Dũng
2021-05-16 15:00:46
#config.php
<?php
define('HOST', 'localhost');
define('USERNAME', 'root');
define('PASSWORD', '');
define('DATABASE', 'BT2290');
define('MD5_PRIVATE_KEY','include.daodung');
?>
#dbhelper.php
<?php
require_once ('config.php');
/**
* Su dung cho lenh: insert/update/delete
*/
function execute($sql) {
// Them du lieu vao database
//B1. Mo ket noi toi database
$conn = mysqli_connect(HOST, USERNAME, PASSWORD, DATABASE);
mysqli_set_charset($conn, 'utf8');
//B2. Thuc hien truy van insert
mysqli_query($conn, $sql);
//B3. Dong ket noi database
mysqli_close($conn);
}
/**
* Su dung cho lenh: select
*/
function executeResult($sql) {
// Them du lieu vao database
//B1. Mo ket noi toi database
$conn = mysqli_connect(HOST, USERNAME, PASSWORD, DATABASE);
mysqli_set_charset($conn, 'utf8');
//B2. Thuc hien truy van insert
$resultset = mysqli_query($conn, $sql);
$data = [];
while (($row = mysqli_fetch_array($resultset, 1)) != null) {
$data[] = $row;
}
//B3. Dong ket noi database
mysqli_close($conn);
return $data;
}
function getPwdSecurity($pwd) {
return md5(md5($pwd).MD5_PRIVATE_KEY);
}
function getGET($key) {
$value = '';
if (isset($_GET[$key])) {
$value = $_GET[$key];
}
$value = fixSqlInjection($value);
return $value;
}
function getPOST($key) {
$value = '';
if (isset($_POST[$key])) {
$value = $_POST[$key];
}
$value = fixSqlInjection($value);
return $value;
}
function fixSqlInjection($str) {
$str = str_replace("\\", "\\\\", $str);
$str = str_replace("'", "\'", $str);
return $str;
}
function valiToken() {
$token = '';
if (isset($_COOKIE['token'])) {
$token = $_COOKIE['token'];
$sql = "select * from users where token = '$token'";
$data = executeResult($sql);
if ($data != null && count($data) > 0) {
return $data[0];
}
}
return null;
}
?>
#cart.php
<?php
require_once ('../db/dbhelper.php');
?>
<!DOCTYPE html>
<html>
<head>
<title>cart Page</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>No</th>
<th>minh họa</th>
<th>tên sản phẩm</th>
<th>số lượng</th>
<th style="width: 50px;"></th>
<th style="width: 50px;"></th>
</tr>
</thead>
<tbody>
<?php
$count = 0;
$cart = json_decode($_COOKIE["cart"]);
foreach ($cart as $item) {
$id = $item->id . PHP_EOL;
$sql = "select * from products where id = ".$id;
$items = executeResult($sql);
$items = $items[0];
echo '<tr>
<td>'.(++$count).'</td>
<td><img src="'.$items['thumbnail'].'" style="width: 80px"></td>
<td>'.$items['title'].'</td>
<td>'.$item->num . PHP_EOL.'</td>
<td><button class="btn btn-warning">Edit</button></td>
<td><button class="btn btn-danger" onclick="deleteUsers(\''.$items['id'].'\')">Delete</button></td>
</tr>';
}
?>
</tbody>
</table>
</div>
</div>
<script type="text/javascript">
function deleteUsers(username) {
option = confirm('Are you sure to delete this user?')
if(!option) return
$.post('form-delete.php', {
'username': username
}, function(data) {//callback -> khi du lieu dc tra ve tu server
location.reload() //load website -> khong load cung dc -> su dung jquery de update data -> tuy vao nghiep cua du an.
})
}
</script>
</body>
</html>
#detail.php
<?php
require_once ('../db/dbhelper.php');
$sql = "select * from products where id=".$_GET['id'];
$items = executeResult($sql);
$item = $items[0];
?>
<!DOCTYPE html>
<html>
<head>
<title><?=$item['title']?></title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div style="display: flex;margin-top: 30px;margin-left: 20px;border: solid 1px gray;">
<div style="width: 30%">
<div style="width: 80%;margin-right: 0px" >
<img src="<?=$item['thumbnail']?>" style="width: 100%;">
</div>
</div>
<div style="width: 60%">
<p>
<?=$item['title']?>
</p>
<br>
<p>
<?=$item['content']?>
</p>
<p>
10.000 vnđ
</p>
<button class="btn btn-success" onclick="addcart(<?=$item['id']?>)">add to cart</button>
</div>
</div>
</div>
<script type="text/javascript">
function addcart(id) {
console.log(document.cookie);
//JSON.parse & JSON.stringify
if(document.cookie == "")
cart = [
{
"id": id,
"num": 1
}
]
else
{
var cartJson = getCookie("cart");
var cart = JSON.parse(cartJson);
var check=0;
for (var i = cart.length - 1; i >= 0; i--) {
if (cart[i]['id']==id) {
cart[i]['num']++;
check=1;
break;
}
}
if(check==0) cart.push({
"id": id,
"num": 1
})
}
setCookie('cart',JSON.stringify(cart),7);
}
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
</script>
</body>
</html>
#products.php
<?php
require_once ('../db/dbhelper.php');
$sql = "select * from products";
$items = executeResult($sql);
?>
<!DOCTYPE html>
<html>
<head>
<title>products Page</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container " style="margin-top: 50px">
<div class="row">
<?php
$count = 0;
foreach ($items as $item) {
echo '
<div class="col-md-3" style="margin-top: 20px">
<div class="card" style="width:100%">
<img class="card-img-top" src="'.$item['thumbnail'].'" alt="Card image" style="width:100%">
<div class="card-body">
<p class="card-text">'.$item['title'].'</p>
<a href="detail.php?id='.$item['id'].'" class="btn btn-primary">detail</a>
</div>
</div>
</div>
';
}
?>
</div>
</div>
</body>
</html>
![GokiSoft.com [Teacher]](https://www.gravatar.com/avatar/fc6ba9324e017d540af3613b3a77dd21.jpg?s=80&d=mm&r=g)
GokiSoft.com
2021-05-13 13:44:09
- Nội dung kiên thức
- overview kiến thức
- Yêu cầu giải đáp vấn đề gì
- Bài test: 60 phút -> check kiến thức
- Kiến thức căn bản: PHP & CSDL
- Kiến thức nâng cao 1 chút -> cách chúng ta vận dụng như nào.
==============================================================
Mục 1: overview kiến thức
- Cookie -> Cách dùng để lưu chữ dữ liệu -> giống như localStorage
- Hiểu về cookie & biết được cách lưu trữ dữ liệu
- Thêm/sửa/xóa cookie:
- JS
- Backend: PHP
Mục 2: Bài tập
===============================================================
BT2290:
B1. Xây dựng database truoc -> database: BT2290
create table products (
id int primary key auto_increment,
title varchar(250),
thumbnail varchar(500),
content text,
created_at datetime,
updated_at datetime
);
create table orders (
id int primary key auto_increment,
fullname varchar(100),
phone_number varchar(20),
address varchar(200),
order_date datetime
);
create table order_details (
id int primary key auto_increment,
order_id int references orders (id),
product_id references products (id),
num int,
price float
);
B2. Fake data
- insert into -> products: 25 ban ghi la ok
B3. Phat trien chuc nang
- products.php -> html/css/js/bootstrap/jquery
-> select * from products (phan trang) -> lay dc du lieu va hien thi ra la ok
-> click 1 product -> detail.php?id=?
- detail.php -> Thiet ke giao dien -> follow theo 1 trang ban hang -> lam theo
-> id tu $_GET -> lay du lieu trong database cua san pham nay $product
-> Hien thi noi dung
-> add to cart -> button -> luu cookie
Giai phap luu cart (bang cookie)
cart => data gio hang -> string
js/php
cart = [
{
"id": ???,
"num": ???
},{
"id": ???,
"num": ???
},
]
- Them du lieu moi
- TH da ton tai -> update num cho san pham tuong ung
cart -> json tring -> cookie
lay du lieu json string tu cookie -> convert array -> su dung (js/php)
js: JSON.parse & JSON.stringify
php: json_encode & json_decode
- cart.php: code bang php
- su dung php -> doc cart trong Cookie
- idList => mang chua id san pham trong gio hang
- select * from products where id in idList (String)
- Hien thi ra giao dien html/css/js...
- checkout.php: code php
- Tham khao thiet ke tren trang thuong mai
- Code nhu trang cart.php
- Form nhap thong tin ship.
- Submit du lieu -> form: thong tin ship hang
- Xu ly data
- $_POST: add vao bang orders -> order id cua don hang
- $_COOKIE: cart -> san pham + so luong -> luu vao trong order_details
- Xu ly xong data -> xoa du lieu khoi cookie => Thanh cong va xong.