商品秒杀 倒计时的实现

商品秒杀倒计时的实现

       前台页面 <index.php>

<meta charset='utf-8'>
<h1>商品秒杀页面</h1>
<?php


//查询今日所有的秒杀信息
$mysqli = new MYSQLi("127.0.0.1","root","root");  
if($mysqli->connect_error){    
    die("连接错误".$mysqli->connect_error);    

//设置字符集
$mysqli->set_charset('utf8');  
$mysqli->select_db("miaosha"); 


//php的时间是以秒算。js的时间以毫秒算  
date_default_timezone_set('PRC');


$sql = "select * from ih_store where to_days(start_time) = to_days(now());";
//执行sql语句
$result = $mysqli->query($sql);
// var_dump($result);die;
//把资源转化为数组
$data = [];
while($arr = $result->fetch_assoc())
{
$data[] = $arr;
}


//获取当前
$time = date("Y-m-d H:i:s",time());
//处理date数据
foreach($data as $k=>$v)
{
//0 表示还没有开始秒杀
//1 表示正在秒杀
//2 表示秒杀已经结束
//判断当前秒杀没有开始
if($v['start_time'] > $time)

{

//往数组中自定义一个字段,用于存放秒杀状态

//也可以传引用的方式(在foreach循环里在$v前加上&,即$&v),这样就可以将$data[$k]替换为$v

$data[$k]['content'] = '0';
}
else if($v['start_time'] <= $time && $v['end_time'] >= $time)
{
$data[$k]['content'] = '1';
}
else
{
$data[$k]['content'] = '2';
}

}
// echo "<pre>";

// print_r($data);exit;


?>
<table border='1'>
<th>秒杀商品</th>
<th>秒杀开始时间</th>
<th>秒杀结束时间</th>
<th>点击秒杀</th>
<?php
foreach($data as $k=>$v){
?>
<tr>
<td>miaosha</td>
<td><?=$v['start_time']?></td>
<td><?=$v['end_time']?></td>
<td>
<?php
if($v['content'] == '0')
{
//调用函数
//date_default_timezone_set("Asia/Hong_Kong");//地区
//配置每天的活动时间段
$starttimestr = $v['start_time'];
$endtimestr = $v['end_time'];
$starttime = strtotime($starttimestr);  //开始时间
$endtime = strtotime($endtimestr);      //结束时间
$nowtime = time();   //当前时间
if ($nowtime<$starttime){
// die("活动还没开始,活动时间是:{$starttimestr}至{$endtimestr}");
}
if ($endtime>=$nowtime){
$lefttime = $starttime-$nowtime; //实际剩下的时间(秒)
}else{
$lefttime=0;
die("活动已经结束!");
}
echo "<span id='a'></span>";
echo "<span id='b'></span>";
}
else if($v['content'] == '1')
{
echo "<a href='miaosha.php'>点我秒杀</a>";
}
else
{
echo '秒杀结束';
}
?>
</td>
</tr>
<?php
}
?>
</table>
<script>
var runtimes = 0;
function GetRTime()
{
var nMS = <?php echo $lefttime; ?>*1000-runtimes*1000;
if(nMS>=0)
{
var nD=Math.floor(nMS/(1000*60*60*24))%24;
var nH=Math.floor(nMS/(1000*60*60))%24;
var nM=Math.floor(nMS/(1000*60)) % 60;
var nS=Math.floor(nMS/1000) % 60;
document.getElementById("a").innerHTML='距离秒杀还有'+nH+'时'+nM+'分'+nS+'秒';
}
if(nMS==5*60*1000)
{
alert("还有最后五分钟!");
}
runtimes++;

setTimeout("GetRTime()",1000);

}
var Num = 0;
onload = function() {
 Refresh();
 setInterval("Refresh();",100);
 GetRTime();
}
function Refresh() {
 if (Num<10){
 document.getElementById("b").innerHTML = Num;
 Num = Num + 1;
 }else{
 Num=0;
 }
}
setTimeout("GetRTime()",1000);
</script>


     <miaosha.php>

采用消息队列的方式

//现将商品库存入队列

  1. <?php  
  2. $store=1000;  
  3. $redis=new Redis();  
  4. $result=$redis->connect('127.0.0.1',6379);  
  5. $res=$redis->llen('goods_store');  
  6. //echo $res;  
  7. $count=$store-$res;  
  8. for($i=0;$i<$count;$i++){  
  9.     $redis->lpush('goods_store',1);  
  10. }  
  11. echo $redis->llen('goods_store');  
  12. ?>  

//抢购、秒杀描述

<?php   
$mysqli = new MYSQLi("127.0.0.1","root","root");
if($mysqli->connect_error){
    die("连接失败".$mysqli->connect_error);

$mysqli->set_charset('utf8');
$mysqli->select_db("miaosha");


$price=10;  
$user_id=1;  
$goods_id=1;  
$sku_id=11;  
$number=1;  
  
//生成唯一订单  
function build_order_no(){  
    return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);  

//记录日志  
function insertLog($event,$type=0){  
    global $mysqli;  
    $sql="insert into ih_log(event,type)   
    values('$event','$type')";    
    $mysqli->query($sql);    
}  
  
//模拟下单操作  
//库存是否大于0  
$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'";//解锁 此时ih_store数据中goods_id='$goods_id' and sku_id='$sku_id' 的数据被锁住(注3),其它事务必须等待此次事务 提交后才能执行  
$rs=$mysqli->query($sql);
// var_dump($rs);exit; 
$row=$rs->fetch_assoc();  
if($row['number']>0){//高并发下会导致超卖  
    $order_sn=build_order_no();  
    //生成订单    
    $sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)   
    values('$order_sn','$user_id','$goods_id','$sku_id','$price')";    
    $order_rs=$mysqli->query($sql);   
      
    //库存减少  
    $sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";  
    $store_rs=$mysqli->query($sql);    
    if($store_rs->affect_rows){    
        insertLog('库存减少成功');  
    }else{    
        insertLog('库存减少失败');  
    }   
}else{  
    insertLog('库存不够');  
}  


/*


优化方案一:
将库存字段设置为unsigned(无符号,即不能有负数);
当库存为0时,因为字段不能为负数,将会返回false
**/


//去库存
// $sql = "update ih_store set number=number-{$number} where sku_id = '$sku_id' and number>0";
// $store_rs = $mysqli->query($sql);
// if($mysqli->affect_rows){
//     insertLog('库存减少成功');
// }


?>  



测试数据表

[php]  view plain  copy
  1. --  
  2. -- 数据库: `miaosha`  
  3. --  
  4.   
  5. -- --------------------------------------------------------  
  6.   
  7. --  
  8. -- 表的结构 `ih_goods`  
  9. --  
  10.   
  11.   
  12. CREATE TABLE IF NOT EXISTS `ih_goods` (  
  13.   `goods_id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  14.   `cat_id` int(11) NOT NULL,  
  15.   `goods_name` varchar(255) NOT NULL,  
  16.   PRIMARY KEY (`goods_id`)  
  17. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;  
  18.   
  19.   
  20. --  
  21. -- 转存表中的数据 `ih_goods`  
  22. --  
  23.   
  24.   
  25. INSERT INTO `ih_goods` (`goods_id`, `cat_id`, `goods_name`) VALUES  
  26. (1, 0, '小米手机');  
  27.   
  28. -- --------------------------------------------------------  
  29.   
  30. --  
  31. -- 表的结构 `ih_log`  
  32. --  
  33.   
  34. CREATE TABLE IF NOT EXISTS `ih_log` (  
  35.   `id` int(11) NOT NULL AUTO_INCREMENT,  
  36.   `event` varchar(255) NOT NULL,  
  37.   `type` tinyint(4) NOT NULL DEFAULT '0',  
  38.   `addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
  39.   PRIMARY KEY (`id`)  
  40. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;  
  41.   
  42. --  
  43. -- 转存表中的数据 `ih_log`  
  44. --  
  45.   
  46.   
  47. -- --------------------------------------------------------  
  48.   
  49. --  
  50. -- 表的结构 `ih_order`  
  51. --  
  52.   
  53. CREATE TABLE IF NOT EXISTS `ih_order` (  
  54.   `id` int(11) NOT NULL AUTO_INCREMENT,  
  55.   `order_sn` char(32) NOT NULL,  
  56.   `user_id` int(11) NOT NULL,  
  57.   `status` int(11) NOT NULL DEFAULT '0',  
  58.   `goods_id` int(11) NOT NULL DEFAULT '0',  
  59.   `sku_id` int(11) NOT NULL DEFAULT '0',  
  60.   `price` float NOT NULL,  
  61.   `addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
  62.   PRIMARY KEY (`id`)  
  63. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单表' AUTO_INCREMENT=1 ;  
  64.   
  65. --  
  66. -- 转存表中的数据 `ih_order`  
  67. --  
  68.   
  69.   
  70. -- --------------------------------------------------------  
  71.   
  72. --  
  73. -- 表的结构 `ih_store`  
  74. --  
  75.   
  76. CREATE TABLE IF NOT EXISTS `ih_store` (  
  77.   `id` int(11) NOT NULL AUTO_INCREMENT,  
  78.   `goods_id` int(11) NOT NULL,  
  79.   `sku_id` int(10) unsigned NOT NULL DEFAULT '0',  
  80.   `number` int(10) NOT NULL DEFAULT '0',  
  81.   `freez` int(11) NOT NULL DEFAULT '0' COMMENT '虚拟库存',  
  82.   PRIMARY KEY (`id`)  
  83. ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='库存' AUTO_INCREMENT=2 ;  
  84.   
  85. --  
  86. -- 转存表中的数据 `ih_store`  
  87. --  
  88.   
  89. INSERT INTO `ih_store` (`id`, `goods_id`, `sku_id`, `number`, `freez`) VALUES  
  90. (1, 1, 11, 500, 0);  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值