溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用php實現(xiàn)取消訂單

發(fā)布時間:2020-07-22 09:35:35 來源:億速云 閱讀:162 作者:Leah 欄目:編程語言

今天就跟大家聊聊有關(guān)如何使用php實現(xiàn)取消訂單,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

php實現(xiàn)取消訂單的方法:首先【order_status】為1時代表客戶下單確定;然后為2時代表客戶已付款;最后為0時代表訂單已取消,運用swoole的異步毫秒定時器。

php實現(xiàn)取消訂單的方法:

一、業(yè)務(wù)場景:當(dāng)客戶下單在指定的時間內(nèi)如果沒有付款,那我們需要將這筆訂單取消掉,比如好的處理方法是運用延時取消,這里我們用到了swoole,運用swoole的異步毫秒定時器不會影響到當(dāng)前程序的運行。

二、說明,order_status為1時代表客戶下單確定,為2時代表客戶已付款,為0時代表訂單已取消(正是swoole來做的),下面的代表我沒有用框架,比較純的PHP代表方便理解和應(yīng)用

三、舉例說明,庫存表csdn_product_stock產(chǎn)品ID為1的產(chǎn)品庫存數(shù)量為20,產(chǎn)品ID為2的庫存數(shù)量為40,然后客戶下單一筆產(chǎn)品ID1減10,產(chǎn)品ID2減20,所以庫存表只夠2次下單,例子中10秒后自動還原庫存,如下圖:

圖解:

1、第一次下完單產(chǎn)品ID1庫存從20減到了10,產(chǎn)品ID2庫存從40減到了20;

2、第二次下完單產(chǎn)品ID的庫存為0了,產(chǎn)品ID2的庫存也為0了;

3、第三次下單時,程序提示Out of stock;

4、過了10秒鐘(每個訂單下單后往后推10秒),客戶兩次下單,由于沒有付款(csdn_order表的order_status為1),產(chǎn)品1和產(chǎn)品2的庫存被還原了(csdn_order表的order_status變?yōu)?),客戶又可以繼續(xù)下單了

如何使用php實現(xiàn)取消訂單

1、所需要sql數(shù)據(jù)庫表

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、order_submit.php

<?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(
'order_amount' => 10.92,
'user_name' => 'yusan',
'order_status' => 1,
'date_created' => 'now()',
'product_lit' => array(
0 => array(
'product_id' => 1,
'product_price' => 5.00,
'product_number' => 10,
'date_created' => 'now()'
),
1 => array(
'product_id' => 2,
'product_price' => 5.92,
'product_number' => 20,
'date_created' => 'now()'
)
)
);
 
try{
$pdo->beginTransaction();//開啟事務(wù)處理
 
$sql = 'insert into csdn_order (order_amount, user_name, order_status, date_created) values (:orderAmount, :userName, :orderStatus, now())';
$stmt = $pdo->prepare($sql);  
$affectedRows = $stmt->execute(array(':orderAmount' => $orderInfo['order_amount'], ':userName' => $orderInfo['user_name'], ':orderStatus' => $orderInfo['order_status']));
$orderId = $pdo->lastInsertId();
if(!$affectedRows) {
throw new PDOException("Failure to submit order!");
}
foreach($orderInfo['product_lit'] as $productInfo) {
 
$sqlProductDetail = 'insert into csdn_order_detail (order_id, product_id, product_price, product_number, date_created) values (:orderId, :productId, :productPrice, :productNumber, now())';
$stmtProductDetail = $pdo->prepare($sqlProductDetail);  
$stmtProductDetail->execute(array(':orderId' => $orderId, ':productId' =>  $productInfo['product_id'], ':productPrice' => $productInfo['product_price'], ':productNumber' => $productInfo['product_number']));
 
$sqlCheck = "select product_stock_number from csdn_product_stock where product_id=:productId";  
$stmtCheck = $pdo->prepare($sqlCheck);  
$stmtCheck->execute(array(':productId' => $productInfo['product_id']));  
$rowCheck = $stmtCheck->fetch(PDO::FETCH_ASSOC);
if($rowCheck['product_stock_number'] < $productInfo['product_number']) {
throw new PDOException("Out of stock, Failure to submit order!");
}
 
 
$sqlProductStock = 'update csdn_product_stock set product_stock_number=product_stock_number-:productNumber, date_modified=now() where product_id=:productId';
$stmtProductStock = $pdo->prepare($sqlProductStock);  
$stmtProductStock->execute(array(':productNumber' => $productInfo['product_number'], ':productId' => $productInfo['product_id']));
$affectedRowsProductStock = $stmtProductStock->rowCount();
 
//庫存沒有正??鄢?,失敗,庫存表里的product_stock_number設(shè)置了為非負(fù)數(shù)
//如果庫存不足時,sql異常:SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in '(`test`.`csdn_product_stock`.`product_stock_number` - 20)'
if($affectedRowsProductStock <= 0) {
throw new PDOException("Out of stock, Failure to submit order!");
}
}
echo "Successful, Order Id is:" . $orderId .",Order Amount is:" . $orderInfo['order_amount'] . "。";
$pdo->commit();//提交事務(wù)
//exec("php order_cancel.php -a" . $orderId . " &");
pclose(popen('php order_cancel.php -a ' . $orderId . ' &', 'w'));
//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、order_cancel.php

<?php
require("config.php");
$queryString = getopt('a:');
$userParams = array($queryString);
appendLog(date("Y-m-d H:i:s") . "\t" . $queryString['a'] . "\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();//開啟事務(wù)處理
 
$orderId = $queryString['a'];  
$sql = "select order_status from csdn_order where order_id=:orderId";  
$stmt = $pdo->prepare($sql);  
$stmt->execute(array(':orderId' => $orderId));  
$row = $stmt->fetch(PDO::FETCH_ASSOC);
//$row['order_status'] === "1"代表已下單,但未付款,我們還原庫存只針對未付款的訂單
if(isset($row['order_status']) && $row['order_status'] === "1") {
$sqlOrderDetail = "select product_id, product_number from csdn_order_detail where order_id=:orderId";  
$stmtOrderDetail = $pdo->prepare($sqlOrderDetail);  
$stmtOrderDetail->execute(array(':orderId' => $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(':productNumber' => $rowOrderDetail['product_number'], ':productId' => $rowOrderDetail['product_id']));
}
 
$sqlRestoreOrder = "update csdn_order set order_status=:orderStatus where order_id=:orderId";  
$stmtRestoreOrder = $pdo->prepare($sqlRestoreOrder);
$stmtRestoreOrder->execute(array(':orderStatus' => 0, ':orderId' => $orderId));
}
 
$pdo->commit();//提交事務(wù)
}catch(PDOException $e){
echo $e->getMessage();
$pdo->rollback();
}
$pdo = null;
 
appendLog(date("Y-m-d H:i:s") . "\t" . $queryString['a'] . "\t" . "end\t" . json_encode($queryString));
}, $pdo);
 
} catch (PDOException $e) {
echo $e->getMessage();
}
function appendLog($str) {
$dir = 'log.txt';
$fh = fopen($dir, "a");
fwrite($fh, $str . "\n");
fclose($fh);
}
?>


看完上述內(nèi)容,你們對如何使用php實現(xiàn)取消訂單有進一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI