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

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


#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)

Đăng nhập để làm bài kiểm tra

Chưa có kết quả nào trước đó