订单是我们在日常开发中经常会遇到的一个功能,最近在做一个订单过期与超时的开发。订单过期与超时就不用我解释了吧,其实两者都是同一个问题来着,就是订单未支付的处理,我们要做的是对这些未支付的订单到了一定时间就自动取消,好了,你第一反应那肯定就是做一个定时任务了!是的,就是定时任务,但是哪个才会是最佳方案呢,下面来看看:
一、前端到时间请求取消
你肯定不会想着在前端来做定时请求取消该订单的,因为如果客户禁用了该应用或者没联网,那到了一定时间时,还一直都是未处理状态的。所以前端一般都是手动去触发取消订单的。
二、服务端定时查询有没有需要取消的订单,然后批量处理。
这种方法我们用得最多的,不过存在准确度的问题,还有需要确认定时任务的周期,但是我们可以结合redis来实现,我们可以在存redis时候顺便存在mysql这样的数据库做长久存储然后用服务端定时查询,这里我用到了redis的订阅功能。
首先先修改一下配置
然后再重启redis
这里创建4个文件
index.php 创建订单,发布消息,10s后查询订单状态并更新订单
<?php
require_once'redis2.class.php';
require_once'db.class.php';
$redis2=new\redis2();
$list=$redis2->lrange('order',0,9999999);
$mysql=new\mysql();
$mysql->connect();
$data=['ordersn'=>'sn'.time().'t'.rand(10000000,99999999),'status'=>0,'createtime'=>date('y-m-dh:i:s',time())];
$mysql->inrt('order',$data);
$order_sn=$data['ordersn'];
$redis2->tex($order_sn,10,$order_sn);
psubscribe.php,发布redis订阅的一些逻辑处理
这里我把re强弩之末的意思dis的一些操作和mysql的一些处理做了封装处理,这个你们可以用到你们自己的项目当中的
redis2.class.php
<?php
classredis2
{
private$redis;
publicfunction__construct($host='127.0.0.1',$port=6379)
{
$this->redis=newredis();
$this->redis->connect($host,$port);
$this->redis->auth('123456');
}
publicfunctiontex($key,$time,$val)
{
return$this->redis->tex($key,$time,$val);
}
publicfunctiont($key,$val)
{
return$this->redis->t($key,$val);
}
publicfunctionget($key)
{
return$this->redis->get($key);
}
publicfunctionexpire($key=null,$time=0)
{
return$this->redis->expire($key,$time);
}
publicfunctionpsubscribe($patterns=array(),$callback)
{
$this->redis->psubscribe($patterns,$callback);
}
publicfunctiontoption()
{
$this->redis->toption(\redis::opt_read_timeout,-1);
}
publicfunctionlrange($key,$start,$end)
{
return$this->redis->lrange($key,$start,$end);
}
publicfunctionlpush($key,$value1,$value2=null,$valuen=null){
return$this->redis->lpush($key,$value1,$value2=null,$valuen=null);
}
publicfunctiondelete($key1,$key2=null,$key3=null)
{
return$this->redis->delete($key1,$key2=null,$key3=null);
}
}
db.class.php,对sql处理的一些封装
<?php
classmysql
{
private$mysqli;
private$result;
/**
*数据库连接
*@param$config配置数组
*/
publicfunctionconnect()
{
$config=array(
'host'=>'127.0.0.1',
'urname'=>'root',
'password'=>'123456qwerty',
'databa'=>'marhal',
'port'=>3306,
);
$host=$config['host'];//主机地址
$urname=$config['urname'];//用户名
$password=$config['password'];//密码
$databa=$config['databa'];//数据库
$port=$config['port'];//端口号
$this->mysqli=newmysqli($host,$urname,$password,$databa,$port);
}
/**
*数据查询
*@param$table数据表
*@paramnull$field字段
*@paramnull$where条件
*@ret数量积公式urnmixed查询结果数目
*/
publicfunctionlect($table,$field=null,$where=null)
{
$sql="lect*from`{$table}`";
//echo$sql;exit;
if(!empty($fi丧礼eld)){
$field='`'.implode('`,`',$field).'`';
$sql=str_replace('*',$field,$sql);
}
if(!empty($where)){
$sql=$sql.'where'.$where;
}
$this->result=$this->mysqli->query($sql);
return$this->result;
}
/**
*@returnmixed获取全部结果
*/
publicfunctionfetchall()
{
return$this->result->fetch_all(mysqli_assoc);
}
/**
*插入数据
*@param$table数据表
*@param$data数据数组
*@returnmixed插入id
*/
publicfunctioninrt($table,$data)
{
foreach($dataas$key=>$value){
$data[$key]=$this->mysqli->real_escape_string($value);
}
$keys='`'.implode('`,`',array_keys($data)).'`';
$values='\''.implode("','",array_values($data)).'\'';
$sql="inrtinto`{$table}`({$keys})values({$values})";
$this->mysqli->query($sql);
return$this->mysqli->inrt_id;
}
/**
*更新数据
*@param$table数据表
*@param$data数据数组
*@param$where过滤条件
*@returnmixed受影响记录
*/
publicfunctionupdate($table,$data,$where)
{
foreach($dataas$key=>$value){
$data[$key]=$this->mysqli->real_escape_string($value);
}
$ts=array();
foreach($dataas$key=>$value){
$kstr='`'.$key.'`';
$vstr='\''.$value.'\'';
array_push($ts,$kstr.'='.$vstr);
}
$kav=implode(',',$ts);
$sql="update`{$table}`t{$kav}where{$where}";
$this->mysqli->query($sql);
return$this->mysqli->affected_rows;
}
/**
*删除数据
*@param$table数据表
*@param$where过滤条件
*@returnmixed受影响记录
*/
publicfunctiondelete($table,$where)
{
$sql="deletefrom`{$table}`where{$where}";
$this-&g有蛔虫的症状t;mysqli->query($sql);
return$this->mysqli->affected_rows;
}
}
对每一次订单的访问我们做了服务器监听任务,如下:
设置本地域名并访问http://www.startphp.cn/index.php
此时,每访问一次index.php,就会创建一个订单,10s钟后,如果该订单依旧处于未支付状态,就设置订单失效。
但是php的cli模式在服务器运行后,总是会掉线,处理这个问题的方法,我们不妨写一个脚本
1.编写shell脚本,定时检查进程是否存在,不存在的话就开启服务,并且将运行情况写入日志
脚本文件如下:
#!/bin/sh
pids=`pidofphp`
if["$pids"!=""];then
echo"在运行"
echo-e$(date+%y"."%m"."%d""%k":"%m":"%s)"running.....">>/mytask/task.run.log
el
echo"不在漂洋过海来看你吉他谱运行,开始启动"
echo-e$(date+%y"."%m"."%d""%k":"%m":"%s)"startphpstart.....">>/mytask/task.start.log
cd/var/www/html/redis
phppsubscribe.php&
echo-e$(date+%y"."%m"."%d""%k":"%m":"%s)"startphpsuccess.....">>/mytask/task.start.log
fi
在crontab任务里创建任务,这里设定的是每5s检查一次,crontab -e
效果你可以查看task.run.log
结果如下:
有需要学习交流的友人请加入交流群的咱们一起,群内都是1-7年的开发者,希望可以一起交流,探讨php,swoole这块的技术 或者有其他问题 也可以问,获取swoole或者php进阶相关资料私聊管理即可
别忘了点赞哦,定期分享干货
点此加入该群jq.qq.com
本文发布于:2023-04-08 00:31:47,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/371adb8fc555b60f97eb9f9219ded6a0.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:PHP如何实现处理过期或者超时订单的,并还原库存.doc
本文 PDF 下载地址:PHP如何实现处理过期或者超时订单的,并还原库存.pdf
留言与评论(共有 0 条评论) |