秒杀 实现 php
redis脚本
<?php
// 功能:将数据库中的库存存储到Redis的list结构中
$redis=new Redis;
$redis->connect('127.0.0.1','6379');
$redis->select(10);
$pdo= new PDO('mysql:host=localhost;dbname=test;','root','root');
$sql="select id,stock from goods";
$data=$pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
// 循环(遍历)所有商品
foreach ($data as $key => $value) {
// 给每个商品在redis中创建一个对应的列表,这个列表的键名是 goods+id值
for($i=1;$i<=$value['stock'];$i++){
$redis->lpush('goods'.$value['id'],$i); // 键是 goods1 goods2 goods3等
}
}
页面编写
<?php
// 读取商品信息
$pdo=new PDO('mysql:host=localhost;dbname=test','root','root');
$sql="select * from goods";
$data=$pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
// echo '<pre/>';
// print_r($data);
?>
<html>
<head>
<title></title>
<script src='jquery.js'></script>
</head>
<body>
<?php foreach($data as $value):?>
<div style='float:left;margin-right:20px;'>
<p>
<span id="h<?=$value['id']?>"></span> 时
<span id="m<?=$value['id']?>"></span> 分
<span id="s<?=$value['id']?>"></span> 秒
</p>
<p><img src="<?=$value['path']?>" width='280' height='200'></p>
<p><?=$value['name']?></p>
<p><?=$value['price']?></p>
<p><input type='button' value='抢购' id="<?=$value['id']?>"></p>
</div>
<?php endforeach;?>
</body>
</html>
<script>
// 倒计时
$(document).ready(function(){
//var i=0;
// 计时器
window.setInterval(function(){
//i++;
//var ajax=new Ajax();
$.ajax({
url:'calctime.php',
type:'get',
dataType:'json',
success:function(data){
//eval("var data = "+data);
for(var i=0;i<data.length;i++){
id=data[i]['id']; // 商品ID
//console.log(id)
$('#h'+id).text(data[i]['hour']);
$('#m'+id).text(data[i]['minute']);
$('#s'+id).text(data[i]['second']);
}
}
});
},1000); // 每秒(1000毫米)执行一次代码
// 抢购按钮加单击事件
$("input[type=button]").click(function(){
var id=$(this).attr('id');
$.ajax({
url:'miaosha.php',
type:'get',
dataType:'json',
data:{'id':id},
success:function(data){
if(data['code']==1){
alert(data['msg']);
}else{
alert(data['msg']);
}
}
});
});
});
</script>
实现页面效果
倒计时实现
<?php
// 前台ajax每秒请求一次此文件,计算一次时间
// 读取商品信息
$pdo=new PDO('mysql:host=localhost;dbname=test','root','root');
$sql="select * from goods";
$data=$pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
// echo '<pre/>';
// print_r($data);
// 计算倒计时
foreach($data as $key=>$value){
//$startTime=$value['starttime'];
$startTime=time();
$endTime=$value['endtime'];
$remainTime=$endTime-$startTime; // 开始时间和结束时间之间相差的秒数
$hour=floor($remainTime/3600); // 1小时是3600秒,所有的秒数除以3600秒,是不就转换成小时了
$minute=floor(($remainTime-$hour*3600)/60); // 分钟
$second=$remainTime-$hour*3600-$minute*60; // 秒
$data[$key]['hour']=$hour;
$data[$key]['minute']=$minute;
$data[$key]['second']=$second;
// echo '<pre/>';
// print_r($data);
}
echo json_encode($data); // 商品数据和倒计时
抢购按钮 成功
<?php
$id=$_GET['id']; // 商品ID
$redis=new Redis;
$redis->connect('127.0.0.1',6379);
$redis->select(10); // 不写此语句,默认是0号数据库
$pdo= new PDO('mysql:host=localhost;dbname=test;','root','root');
// 使用redis中的list类型(列表,也叫队列)控制高并发下的超卖问题
// 来一个请求,则从队列中移除一个元素,llen是获取队列长度(队列中元素数量)
$key='goods'.$id; // 键名
// 过来一个请求,则判断一下redis list中是否还有元素(队列长度是否大于0),如果有元素,则退队一个元素,同时库存减1
if($redis->llen($key)>0){
$redis->lpop($key); // 从队列中移除一个元素
// 库存减1
$sql="update goods set stock=stock-1 where id=$id";
// 向order表中添加记录————生成订单
$order_id=date('Ymd',time()).md5(rand(100,999)); // 订单号,你可以随便生成
$addtime=time();
$sql1="insert into order(order_id,goods_id,addtime) values('$order_id',$id,$addtime)";
// 如果库存减1执行成功,则进一步向订单表中添加记录记录,同时向前台返回提示信息
if($data=$pdo->exec($sql)){
$pdo->exec($sql1); // 向订单表中添加记录
echo json_encode(['code'=>1,'msg'=>'秒杀成功!']); // 向前台返回数据
}
}else{
echo json_encode(['code'=>0,'id'=>$id,'msg'=>'秒杀结束!']);
}

浙公网安备 33010602011771号