当前位置:首页 > PHP

php实现抢购

2026-02-13 22:41:16PHP

PHP实现抢购功能

抢购功能需要处理高并发请求,确保数据的准确性和系统的稳定性。以下是实现抢购功能的关键步骤:

数据库设计 创建商品表和订单表,商品表需包含库存字段,订单表记录抢购成功的用户信息。使用事务和锁机制保证数据一致性。

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `stock` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE `order` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `product_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
);

悲观锁实现 在查询商品库存时使用SELECT FOR UPDATE锁定记录,防止其他进程同时修改。

$pdo->beginTransaction();
try {
    $stmt = $pdo->prepare("SELECT stock FROM product WHERE id = ? FOR UPDATE");
    $stmt->execute([$productId]);
    $product = $stmt->fetch();

    if ($product['stock'] > 0) {
        $pdo->prepare("UPDATE product SET stock = stock - 1 WHERE id = ?")->execute([$productId]);
        $pdo->prepare("INSERT INTO `order` (product_id, user_id) VALUES (?, ?)")->execute([$productId, $userId]);
        $pdo->commit();
        echo "抢购成功";
    } else {
        $pdo->rollBack();
        echo "库存不足";
    }
} catch (Exception $e) {
    $pdo->rollBack();
    echo "系统繁忙";
}

Redis缓存和队列 使用Redis原子操作减轻数据库压力,先将请求放入队列再异步处理。

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 检查库存
$stock = $redis->get("product_stock_{$productId}");
if ($stock <= 0) {
    echo "已售罄";
    exit;
}

// 原子减库存
$remain = $redis->decr("product_stock_{$productId}");
if ($remain >= 0) {
    // 将订单信息放入队列
    $orderData = json_encode(['product_id' => $productId, 'user_id' => $userId]);
    $redis->lPush('order_queue', $orderData);
    echo "抢购成功";
} else {
    $redis->incr("product_stock_{$productId}"); // 恢复库存
    echo "库存不足";
}

限流措施 使用Redis实现计数器限流,防止系统过载。

$key = "user_request_{$userId}";
$limit = 5; // 每秒限制5次请求

if ($redis->incr($key) > $limit) {
    echo "请求过于频繁";
    exit;
}
$redis->expire($key, 1); // 1秒过期

静态化页面 将商品详情页生成静态HTML,减少服务器动态请求压力。使用Nginx直接返回静态文件。

分布式锁 在集群环境下使用Redis实现分布式锁,确保同一时间只有一个进程处理库存扣减。

$lockKey = "product_lock_{$productId}";
$randomValue = uniqid();
$locked = $redis->set($lockKey, $randomValue, ['NX', 'EX' => 10]);

if ($locked) {
    try {
        // 处理抢购逻辑
    } finally {
        // 确保释放自己的锁
        if ($redis->get($lockKey) == $randomValue) {
            $redis->del($lockKey);
        }
    }
} else {
    echo "系统繁忙";
}

异步处理 使用消息队列将订单处理与抢购请求分离,提高响应速度。RabbitMQ或Kafka都是可选方案。

库存预热 活动开始前将库存加载到Redis,避免直接查询数据库。定时同步Redis和数据库的库存数据。

验证码机制 在抢购前增加图形验证码或短信验证码,防止机器人刷单。

php实现抢购

标签: php
分享给朋友:

相关文章

php实现打印功能

php实现打印功能

PHP 实现打印功能的方法 PHP 可以通过多种方式实现打印功能,具体取决于打印的目标(如打印机、PDF、网页等)和需求(如直接打印、生成打印预览等)。以下是几种常见的实现方式: 使用 JavaSc…

php实现分页

php实现分页

PHP实现分页的基本方法 使用LIMIT和OFFSET进行数据库查询分页。通过计算当前页码和每页显示数量,动态生成SQL语句。 $page = isset($_GET['page']) ? (int…

php 实现自动收货

php 实现自动收货

PHP 实现自动收货功能 自动收货功能通常用于电商系统,在订单超过一定时间未手动确认收货时自动完成订单。以下是实现方法: 数据库设计 需要订单表包含以下关键字段: CREATE TABLE o…

git php实现

git php实现

Git 与 PHP 的集成实现 使用 PHP 执行 Git 命令 通过 PHP 的 exec()、shell_exec() 或 passthru() 函数可以直接调用 Git 命令,适用于服务器端操作…

php实现栈

php实现栈

栈的基本概念 栈(Stack)是一种遵循后进先出(LIFO)原则的数据结构。核心操作包括: push:元素入栈。 pop:元素出栈(返回并移除栈顶元素)。 peek:查看栈顶元素(不移…

php实现队列

php实现队列

PHP实现队列的方法 队列是一种先进先出(FIFO)的数据结构,PHP可以通过多种方式实现队列功能。 使用数组模拟队列 PHP数组可以模拟队列的基本操作,通过array_push和array_sh…