search
HomeBackend DevelopmentPHP ProblemHow to cancel an order in php?

How to cancel an order in php?

Jul 10, 2020 am 10:31 AM
phpcancel order

php method to implement order cancellation: first, when [order_status] is 1, it means that the customer has placed an order; then when it is 2, it means that the customer has paid; and finally when it is 0, it means that the order has been cancelled, using swoole's asynchronous millisecond timing device.

How to cancel an order in php?

php method to cancel an order:

1. Business scenario: When a customer places an order at a specified time If there is no payment within the time limit, then we need to cancel the order. For example, a good way to deal with it is to use delayed cancellation. Here we use swoole. Using swoole's asynchronous millisecond timer will not affect the current The operation of the program.

2. Description, when order_status is 1, it means that the customer has placed an order, when it is 2, it means that the customer has paid, and when it is 0, it means that the order has been canceled (this is what swoole does). I don’t use a framework for the following representation. The relatively pure PHP representation is easy to understand and apply.

3. For example, in the inventory table csdn_product_stock, the inventory quantity of the product with product ID 1 is 20, and the inventory quantity with product ID 2 is 40, then when the customer places an order, product ID1 will be reduced by 10, and product ID2 will be reduced by 20, so the inventory table is only enough for 2 orders. In the example, the inventory will be automatically restored after 10 seconds, as shown below:

Illustration:

1. After placing the first order, the inventory of product ID1 was reduced from 20 to 10, and the inventory of product ID2 was reduced from 40 to 20;

2. After placing the second order, the inventory of product ID was 0. , the inventory of product ID2 is also 0;

3. When placing an order for the third time, the program prompts Out of stock;

4. After 10 seconds (each order is placed 10 seconds later), the customer placed orders twice. Since there was no payment (the order_status of the csdn_order table was 1), the inventory of product 1 and product 2 was restored (the order_status of the csdn_order table became 0), and the customer could continue. Placed an order

How to cancel an order in php?

1. Required sql database table

DROP TABLE IF EXISTS `csdn_order`;
CREATE TABLE `csdn_order` (
  `order_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_amount` float(10,2) unsigned NOT NULL DEFAULT '0.00',
  `user_name` varchar(64) CHARACTER SET latin1 NOT NULL DEFAULT '',
  `order_status` tinyint(2) unsigned NOT NULL DEFAULT '0',
  `date_created` datetime NOT NULL,
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
 
DROP TABLE IF EXISTS `csdn_order_detail`;
CREATE TABLE `csdn_order_detail` (
  `detail_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_id` int(10) unsigned NOT NULL,
  `product_id` int(10) NOT NULL,
  `product_price` float(10,2) NOT NULL,
  `product_number` smallint(4) unsigned NOT NULL DEFAULT '0',
  `date_created` datetime NOT NULL,
  PRIMARY KEY (`detail_id`),
  KEY `idx_order_id` (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
 
DROP TABLE IF EXISTS `csdn_product_stock`;
CREATE TABLE `csdn_product_stock` (
  `auto_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `product_id` int(10) NOT NULL,
  `product_stock_number` int(10) unsigned NOT NULL,
  `date_modified` datetime NOT NULL,
  PRIMARY KEY (`auto_id`),
  KEY `idx_product_id` (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
 
INSERT INTO `csdn_product_stock` VALUES ('1', '1', '20', '2018-09-13 19:36:19');
INSERT INTO `csdn_product_stock` VALUES ('2', '2', '40', '2018-09-13 19:36:19');

2.config.php

<?php
$dbHost = "192.168.0.110";
$dbUser = "root";
$dbPassword = "123";
$dbName = "test";
?>

3、<strong>order_submit.php</strong>

<?php
require("config.php");
try {
$pdo = new PDO("mysql:host=" . $dbHost . ";dbname=" . $dbName, $dbUser, $dbPassword, array(PDO::ATTR_PERSISTENT => true));
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
$orderInfo = array(
&#39;order_amount&#39; => 10.92,
&#39;user_name&#39; => &#39;yusan&#39;,
&#39;order_status&#39; => 1,
&#39;date_created&#39; => &#39;now()&#39;,
&#39;product_lit&#39; => array(
0 => array(
&#39;product_id&#39; => 1,
&#39;product_price&#39; => 5.00,
&#39;product_number&#39; => 10,
&#39;date_created&#39; => &#39;now()&#39;
),
1 => array(
&#39;product_id&#39; => 2,
&#39;product_price&#39; => 5.92,
&#39;product_number&#39; => 20,
&#39;date_created&#39; => &#39;now()&#39;
)
)
);
 
try{
$pdo->beginTransaction();//开启事务处理
 
$sql = &#39;insert into csdn_order (order_amount, user_name, order_status, date_created) values (:orderAmount, :userName, :orderStatus, now())&#39;;
$stmt = $pdo->prepare($sql);  
$affectedRows = $stmt->execute(array(&#39;:orderAmount&#39; => $orderInfo[&#39;order_amount&#39;], &#39;:userName&#39; => $orderInfo[&#39;user_name&#39;], &#39;:orderStatus&#39; => $orderInfo[&#39;order_status&#39;]));
$orderId = $pdo->lastInsertId();
if(!$affectedRows) {
throw new PDOException("Failure to submit order!");
}
foreach($orderInfo[&#39;product_lit&#39;] as $productInfo) {
 
$sqlProductDetail = &#39;insert into csdn_order_detail (order_id, product_id, product_price, product_number, date_created) values (:orderId, :productId, :productPrice, :productNumber, now())&#39;;
$stmtProductDetail = $pdo->prepare($sqlProductDetail);  
$stmtProductDetail->execute(array(&#39;:orderId&#39; => $orderId, &#39;:productId&#39; =>  $productInfo[&#39;product_id&#39;], &#39;:productPrice&#39; => $productInfo[&#39;product_price&#39;], &#39;:productNumber&#39; => $productInfo[&#39;product_number&#39;]));
 
$sqlCheck = "select product_stock_number from csdn_product_stock where product_id=:productId";  
$stmtCheck = $pdo->prepare($sqlCheck);  
$stmtCheck->execute(array(&#39;:productId&#39; => $productInfo[&#39;product_id&#39;]));  
$rowCheck = $stmtCheck->fetch(PDO::FETCH_ASSOC);
if($rowCheck[&#39;product_stock_number&#39;] < $productInfo[&#39;product_number&#39;]) {
throw new PDOException("Out of stock, Failure to submit order!");
}
 
 
$sqlProductStock = &#39;update csdn_product_stock set product_stock_number=product_stock_number-:productNumber, date_modified=now() where product_id=:productId&#39;;
$stmtProductStock = $pdo->prepare($sqlProductStock);  
$stmtProductStock->execute(array(&#39;:productNumber&#39; => $productInfo[&#39;product_number&#39;], &#39;:productId&#39; => $productInfo[&#39;product_id&#39;]));
$affectedRowsProductStock = $stmtProductStock->rowCount();
 
//库存没有正常扣除,失败,库存表里的product_stock_number设置了为非负数
//如果库存不足时,sql异常:SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in &#39;(`test`.`csdn_product_stock`.`product_stock_number` - 20)&#39;
if($affectedRowsProductStock <= 0) {
throw new PDOException("Out of stock, Failure to submit order!");
}
}
echo "Successful, Order Id is:" . $orderId .",Order Amount is:" . $orderInfo[&#39;order_amount&#39;] . "。";
$pdo->commit();//提交事务
//exec("php order_cancel.php -a" . $orderId . " &");
pclose(popen(&#39;php order_cancel.php -a &#39; . $orderId . &#39; &&#39;, &#39;w&#39;));
//system("php order_cancel.php -a" . $orderId . " &", $phpResult);
//echo $phpResult;
}catch(PDOException $e){
echo $e->getMessage();
$pdo->rollback();
}
$pdo = null;
} catch (PDOException $e) {
    echo $e->getMessage();
}
?>

4. <strong>order_cancel.php</strong>

<?php
require("config.php");
$queryString = getopt(&#39;a:&#39;);
$userParams = array($queryString);
appendLog(date("Y-m-d H:i:s") . "\t" . $queryString[&#39;a&#39;] . "\t" . "start");
 
try {
$pdo = new PDO("mysql:host=" . $dbHost . ";dbname=" . $dbName, $dbUser, $dbPassword, array(PDO::ATTR_PERSISTENT => true));
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
swoole_timer_after(10000, function ($queryString) {
global $queryString, $pdo;
 
try{
$pdo->beginTransaction();//开启事务处理
 
$orderId = $queryString[&#39;a&#39;];  
$sql = "select order_status from csdn_order where order_id=:orderId";  
$stmt = $pdo->prepare($sql);  
$stmt->execute(array(&#39;:orderId&#39; => $orderId));  
$row = $stmt->fetch(PDO::FETCH_ASSOC);
//$row[&#39;order_status&#39;] === "1"代表已下单,但未付款,我们还原库存只针对未付款的订单
if(isset($row[&#39;order_status&#39;]) && $row[&#39;order_status&#39;] === "1") {
$sqlOrderDetail = "select product_id, product_number from csdn_order_detail where order_id=:orderId";  
$stmtOrderDetail = $pdo->prepare($sqlOrderDetail);  
$stmtOrderDetail->execute(array(&#39;:orderId&#39; => $orderId));  
while($rowOrderDetail = $stmtOrderDetail->fetch(PDO::FETCH_ASSOC)) {
$sqlRestoreStock = "update csdn_product_stock set product_stock_number=product_stock_number + :productNumber, date_modified=now() where product_id=:productId";  
$stmtRestoreStock = $pdo->prepare($sqlRestoreStock);
$stmtRestoreStock->execute(array(&#39;:productNumber&#39; => $rowOrderDetail[&#39;product_number&#39;], &#39;:productId&#39; => $rowOrderDetail[&#39;product_id&#39;]));
}
 
$sqlRestoreOrder = "update csdn_order set order_status=:orderStatus where order_id=:orderId";  
$stmtRestoreOrder = $pdo->prepare($sqlRestoreOrder);
$stmtRestoreOrder->execute(array(&#39;:orderStatus&#39; => 0, &#39;:orderId&#39; => $orderId));
}
 
$pdo->commit();//提交事务
}catch(PDOException $e){
echo $e->getMessage();
$pdo->rollback();
}
$pdo = null;
 
appendLog(date("Y-m-d H:i:s") . "\t" . $queryString[&#39;a&#39;] . "\t" . "end\t" . json_encode($queryString));
}, $pdo);
 
} catch (PDOException $e) {
echo $e->getMessage();
}
function appendLog($str) {
$dir = &#39;log.txt&#39;;
$fh = fopen($dir, "a");
fwrite($fh, $str . "\n");
fclose($fh);
}
?>

Related learning recommendations: PHP programming from entry to proficiency

The above is the detailed content of How to cancel an order in php?. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.