秒杀 实现 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'=>'秒杀结束!']);	
}

  

posted @ 2020-11-22 20:12  拉斯维加斯  阅读(317)  评论(0)    收藏  举报