>백엔드 개발 >PHP 문제 >PHP에서 주문을 취소하는 방법은 무엇입니까?

PHP에서 주문을 취소하는 방법은 무엇입니까?

coldplay.xixi
coldplay.xixi원래의
2020-07-10 10:31:243267검색

PHP에서 주문을 취소하는 방법: 먼저, [order_status]가 1이면 고객이 주문했다는 뜻이고, 2이면 고객이 결제했다는 의미입니다. swoole의 비동기 밀리초 타이머를 사용하여 주문이 취소되었습니다.

PHP에서 주문을 취소하는 방법은 무엇입니까?

PHP에서 주문을 취소하는 방법:

1. 비즈니스 시나리오: 고객이 주문을 하고 지정된 시간 내에 지불하지 않으면 상품과 같은 주문을 취소해야 합니다. 처리 방법 여기서는 swoole을 사용합니다. swoole의 비동기 밀리초 타이머를 사용하면 현재 프로그램 실행에 영향을 미치지 않습니다. swoole,运用swoole的异步毫秒定时器不会影响到当前程序的运行。

二、说明,order_status为1时代表客户下单确定,为2时代表客户已付款,为0时代表订单已取消(正是swoole来做的),下面的代表我没有用框架,比较纯的PHP代表方便理解和应用

三、举例说明,库存表csdn_product_stock产品ID为1的产品库存数量为20,产品ID为2的库存数量为40,然后客户下单一笔产品ID1减10,产品ID2减20,所以库存表只够2次下单,例子中10秒后自动还原库存,如下图:

图解:

1、第一次下完单产品ID1库存从20减到了10,产品ID2库存从40减到了20;

2、第二次下完单产品ID的库存为0了,产品ID2的库存也为0了;

3、第三次下单时,程序提示Out of stock;

4、过了10秒钟(每个订单下单后往后推10秒),客户两次下单,由于没有付款(csdn_order表的order_status为1),产品1和产品2的库存被还原了(csdn_order表的order_status变为0),客户又可以继续下单了

PHP에서 주문을 취소하는 방법은 무엇입니까?

1、所需要sql数据库表

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>

2. 설명, order_status가 1이면 고객이 주문했다는 의미, 2이면 고객이 결제했다는 의미, 0이면 주문이 완료되었음을 의미합니다. 취소됨(swoole이 하는 일) 다음은 프레임워크를 사용하지 않았음을 나타냅니다. 상대적으로 순수한 PHP는 이해하기 쉽고 적용이 용이함을 나타냅니다

3. 예를 들어, 재고 테이블 csdn_product_stock에서 제품 ID가 있는 제품의 재고 수량입니다. 1은 20이고, 제품 ID 2의 재고 수량은 40이며, 고객이 주문하면 제품 ID1이 10개, 제품 ID2가 20개 줄어들므로 재고 테이블에는 2개의 주문만 가능합니다. 예를 들어 아래와 같이 10초 후에 재고가 자동으로 복원됩니다. 그림:

1. 첫 주문 후 제품 ID1의 재고가 20개부터 10개로 줄어들었고, 제품 ID2의 재고는 10개로 줄었습니다. 40개에서 20개로 줄었습니다. 🎜🎜2. 두 번째 주문 후 제품 ID의 재고는 0이고, 세 번째 주문 후 제품 ID도 0입니다. 🎜🎜4. 10초 후(각 주문이 접수된 후 10초 뒤로 이동) 고객이 결제를 하지 않았기 때문에(csdn_order 테이블의 order_status는 1입니다.) 1 및 제품 2가 복원되었으며(csdn_order 테이블의 order_status가 0이 됨) 고객은 계속 주문할 수 있습니다🎜🎜PHP에서 주문을 취소하는 방법은 무엇입니까?🎜🎜🎜1. 필수 SQL 데이터베이스 테이블🎜🎜
<?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);
}
?>
🎜 🎜2. config.php 🎜🎜 rrreee🎜 🎜🎜🎜3, 🎜🎜order_submit.php🎜🎜rrreee🎜🎜4, 🎜🎜order_cancel.php🎜🎜rrreee🎜🎜관련 학습 권장 사항: 🎜 PHP 프로그래밍 입학부터 마스터까지🎜🎜🎜

위 내용은 PHP에서 주문을 취소하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.