您好,欢迎访问一九零五行业门户网

php如何实现取消订单?

php实现取消订单的方法:首先【order_status】为1时代表客户下单确定;然后为2时代表客户已付款;最后为0时代表订单已取消,运用swoole的异步毫秒定时器。
php实现取消订单的方法:
一、业务场景:当客户下单在指定的时间内如果没有付款,那我们需要将这笔订单取消掉,比如好的处理方法是运用延时取消,这里我们用到了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),客户又可以继续下单了
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、order_submit.php
<?phprequire("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();//开启事务处理 $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设置了为非负数//如果库存不足时,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();//提交事务//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
<?phprequire("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();//开启事务处理 $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();//提交事务}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);}?>
相关学习推荐:php编程从入门到精通
以上就是php如何实现取消订单?的详细内容。
其它类似信息

推荐信息