- 先创建3个表,goods(产品表),order(订单表), order_log(订单日志)
CREATE TABLE `order` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`out_order_id` varchar(20) NULL COMMENT '我们的外部单号',
`trade_no` varchar(50) NULL COMMENT '微信/支付宝单号',
`money` decimal(10,2) UNSIGNED NULL,
`status` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '0 未支付,1已支付,2 已完成 ,3 已取消',
`member_id` int(10) UNSIGNED NULL,
`goods_id` int(10) UNSIGNED NULL,
`goods_num` int(10) UNSIGNED NULL,
`create_time` int UNSIGNED NULL,
`pay_time` int(10) UNSIGNED NULL,
`finish_time` int(10) UNSIGNED NULL,
PRIMARY KEY (`id`)
)
COMMENT = '订单表';
CREATE TABLE `goods` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(200) NULL,
`price` decimal(8,2) UNSIGNED NULL,
`pic` varchar(200) NULL,
`inventory` int(10) UNSIGNED NULL,
`create_time` int(10) UNSIGNED NULL,
`update_time` int(10) UNSIGNED NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `order_log` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`status` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '0 错误, 1 正常',
`msg` text NULL,
`create_time` int(10) UNSIGNED NULL,
PRIMARY KEY (`id`)
);
2. 控制器
先检查redis 连接,执行: $this->check_redis();
// 检测 redis 连接
public function check_redis(){
$redis = new Redis();
$redis->connect('127.0.0.1', 6379,2);// 127.0.0.1 连接的IP,6379 连接的端口,2 连接的超时时长,单位:秒
// $redis->auth('123456'); // redis 的密码,有设置就要填
$res = $redis->ping(); // 检测当前链接状态,返回PONG或者抛出异常。
if($res === '+PONG'){
echo '连接成功';
}else{
echo '连接失败';
}
}
插入产品信息,执行: $this->set_pro();
// 连接redis
public function link_redis(){
$redis = new Redis();
$redis->connect('127.0.0.1', 6379,2);// 127.0.0.1 连接的IP,6379 连接的端口,2 连接的超时时长,单位:秒
return $redis;
}
// 添加产品信息和数量
public function set_pro(){
// 添加产品信息
$data = [
'id' => 1, // 产品id = 1
'name' => '测试产品1',// 产品名称
'price' => '97', // 价格97 元
'inventory' => 100,// 库存设置100
'create_time' => time(),
'update_time' => time(),
];
Db::name('goods')->insert($data);
$redis = $this->link_redis();
// 设置一个数组 pro_1 ,内含100个元素
for($i=0; $i < 100; $i++){
$redis->rPush('pro_1', $i);
}
// // 查看pro_1 数组
// $num = $redis->lRange('pro_1',0,-1);
// print_r($num);
}
订单部分:
执行:$this->start_task();
查看数据库,数据记录正确。
开始并发测试。并发测试方法步骤查看 Redis & Tp5 的秒杀订单(一) 第四部分
// 查询缓存,下单
public function start_task(){
$goods_id = 1;// 订单的产品id
$goods_num = 2;// 订单的产品数量
$goods = Db::name('goods')->find($goods_id);// 产品信息获取
$redis = $this->link_redis();
$inventory = $redis->llen('pro_1');// 查看数组长度
if(($inventory == 0) || ($inventory < $goods_num) || ($goods['inventory'] < $goods_num) ){
$this->log(0,'产品:'.$goods['name'].'( id :'.$goods_id.' ) 库存不足');
echo '库存不足';// 返回库存不足的信息给客户
}else{
// 缓存库存 - 对应的产品库存
for($j=0;$j<$goods_num;$j++){
$redis->rpop('pro_1');// 从当前数组中取出1个元素
}
$this->create_order($goods,$goods_num);// 创建订单
Db::name('goods')->where('id',$goods_id)->setDec('inventory',$goods_num);// 数据库 - 商品库存扣除
// 这里可添加订单完成后的相关操作
$this->log(1,'添加订单成功');
echo '订单成功';// 返回订单成功的信息给客户
}
}
// 创建订单
public function create_order($goods,$goods_num){
$order = [
'out_order_id' => $this->getRandomString(4),
'goods_id' => $goods['id'],
'goods_num' => $goods_num,
'money' => $goods['price'] * $goods_num,
'create_time' => time(),
];
$res = Db::name('order')->insert($order);
if(!$res){
$this->log(0,'添加订单失败');
echo '添加订单失败';
return false;
}
}
// 日志
public function log($status,$msg){
$log = [
'status' => $status,
'msg' => $msg,
'create_time' => time(),
];
Db::name('order_log')->insert($log);
}
//随机生成字母和数字的组合
public function getRandomString($len, $chars=null){
if (is_null($chars)) {
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
}
mt_srand(10000000*(double)microtime());
for ($i = 0, $str = '', $lc = strlen($chars)-1; $i < $len; $i++) {
$str .= $chars[mt_rand(0, $lc)];
}
return $str;
}