PHP项目怎样实现商品库存预警?

wen PHP项目 19

本文目录导读:

PHP项目怎样实现商品库存预警?

  1. 核心数据与逻辑
  2. 获取预警商品列表
  3. 通知机制(如何让人知道)
  4. 高级优化与最佳实践

实现PHP项目中的商品库存预警,核心思路是设置阈值 + 定时或实时检查 + 通知相关方

下面我会分几个层级来讲解实现方案,从基础的数据库设计到中级的通知机制,再到高级的优化建议。

核心数据与逻辑

你需要一个合理的数据库结构来存储库存和阈值。

数据库表设计

假设你有一个商品表 products,通常需要以下关键字段:

-- 商品表
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    sku VARCHAR(100) UNIQUE, -- 库存量单位
    stock_quantity INT NOT NULL DEFAULT 0, -- 当前库存数量
    low_stock_threshold INT NOT NULL DEFAULT 10, -- 低库存预警阈值
    status TINYINT DEFAULT 1, -- 1:正常 2:预警 3:缺货
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
  • stock_quantity:实时更新,每次出库/入库都修改它。
  • low_stock_threshold每个商品可以单独设置,比如A商品低于5个预警,B商品低于50个预警。
  • status:可以作为一个冗余字段,方便快速查询哪些商品处于预警状态,避免每次查询都做比较运算。

核心判断逻辑(PHP代码片段)

当发生订单出库、退货入库等操作时,更新库存并立即检查是否触发预警。

<?php
class InventoryService
{
    private $db; // PDO连接
    public function __construct($pdo)
    {
        $this->db = $pdo;
    }
    /**
     * 出库操作并检查预警
     * @param int $productId 商品ID
     * @param int $quantity 出库数量
     * @return array 返回状态信息
     */
    public function decreaseStockAndCheckAlert(int $productId, int $quantity): array
    {
        // 1. 开始事务
        $this->db->beginTransaction();
        try {
            // 2. 获取当前库存和阈值(使用行锁或乐观锁防止高并发超卖)
            $sql = "SELECT stock_quantity, low_stock_threshold FROM products WHERE id = ? FOR UPDATE";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$productId]);
            $product = $stmt->fetch(PDO::FETCH_ASSOC);
            if (!$product) {
                throw new \Exception('商品不存在');
            }
            $currentStock = (int)$product['stock_quantity'];
            $threshold = (int)$product['low_stock_threshold'];
            // 3. 检查库存是否充足
            if ($currentStock < $quantity) {
                throw new \Exception('库存不足,当前库存:' . $currentStock);
            }
            // 4. 更新库存
            $newStock = $currentStock - $quantity;
            $updateSql = "UPDATE products SET stock_quantity = ? WHERE id = ?";
            $updateStmt = $this->db->prepare($updateSql);
            $updateStmt->execute([$newStock, $productId]);
            // 5. 判断是否需要预警
            $alertInfo = $this->checkAndTriggerAlert($productId, $newStock, $threshold);
            // 6. 提交事务
            $this->db->commit();
            return [
                'success' => true,
                'new_stock' => $newStock,
                'alert_triggered' => $alertInfo['triggered'],
                'message' => $alertInfo['message']
            ];
        } catch (\Exception $e) {
            $this->db->rollBack();
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }
    /**
     * 检查并触发预警
     */
    private function checkAndTriggerAlert(int $productId, int $stock, int $threshold): array
    {
        $triggered = false;
        $status = 1; // 正常
        $message = '';
        if ($stock <= 0) {
            $status = 3; // 缺货
            $triggered = true;
            $message = '严重预警:商品 ID ' . $productId . ' 已缺货!';
        } elseif ($stock <= $threshold) {
            $status = 2; // 低库存预警
            $triggered = true;
            $message = '预警:商品 ID ' . $productId . ' 库存低于阈值(当前:' . $stock . ',阈值:' . $threshold . ')';
        }
        // 更新商品状态(可选,但推荐)
        $updateStatusSql = "UPDATE products SET status = ? WHERE id = ?";
        $stmt = $this->db->prepare($updateStatusSql);
        $stmt->execute([$status, $productId]);
        return [
            'triggered' => $triggered,
            'message' => $message
        ];
    }
}

关键点:

  • 行锁 (FOR UPDATE):在高并发下防止超卖,确保扣减库存和检查逻辑是原子性的。
  • 阈值可配置:每个商品都应有独立的 low_stock_threshold

获取预警商品列表

哪些商品需要补货?后台管理页面经常需要这个列表。

<?php
/**
 * 获取所有需要补货的商品列表
 * @param PDO $pdo
 * @return array
 */
function getLowStockAlerts(PDO $pdo): array
{
    $sql = "SELECT id, name, sku, stock_quantity, low_stock_threshold 
            FROM products 
            WHERE stock_quantity <= low_stock_threshold 
            ORDER BY (stock_quantity - low_stock_threshold) ASC";
    $stmt = $pdo->query($sql);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 使用示例
$lowStockProducts = getLowStockAlerts($pdo);
foreach ($lowStockProducts as $product) {
    echo "商品:" . $product['name'] . ",当前库存:" . $product['stock_quantity'] . ",阈值:" . $product['low_stock_threshold'] . PHP_EOL;
}

优化建议: 在这个查询的 stock_quantitylow_stock_threshold 字段上建立复合索引,可以极大提升查询性能。

ALTER TABLE products ADD INDEX idx_stock_alert (stock_quantity, low_stock_threshold);

通知机制(如何让人知道)

光查出数据还不够,你需要主动通知运营或仓库人员。

实时通知(在出库/入库操作时触发)

decreaseStockAndCheckAlert 方法的最后,如果发现预警,可以:

  • 日志记录:写入 inventory_alert_logs 表。
  • 消息队列:向 RabbitMQ / Redis 列表推送一条任务,由异步消费者去处理发送邮件/短信。
  • WebSocket:后台管理界面实时弹出通知(适合后台管理员场景)。

定时任务通知(适合不需要实时响应的场景)

使用 Linux CrontabWindows 任务计划 定时执行一个 PHP 脚本。

Crontab 示例(每天上午9点检查一次)

0 9 * * * /usr/bin/php /var/www/html/cron/check_stock_alert.php

PHP 脚本示例 (check_stock_alert.php)

<?php
// 引入数据库连接和发送邮件的类
$alertProducts = getLowStockAlerts($pdo);
if (!empty($alertProducts)) {
    $subject = '【库存预警】系统发现 ' . count($alertProducts) . ' 个商品需要补货';
    $body = "以下是库存不足的商品清单:\n\n";
    foreach ($alertProducts as $p) {
        $body .= "商品: {$p['name']} (SKU: {$p['sku']}) | 当前库存: {$p['stock_quantity']} | 阈值: {$p['low_stock_threshold']}\n";
    }
    // 发送邮件或企业微信/钉钉机器人消息
    // sendEmail('admin@yourstore.com', $subject, $body);
    // sendWeComRobot('YOUR_WECOM_KEY', $subject, $body);
}
echo "检查完成,发现 " . count($alertProducts) . " 个预警商品。\n";

通知方式建议(按重要程度排列)

方式 适用场景 优点 缺点
邮件 批量、非紧急 成本低,信息详细 可能有延迟,容易被忽略
短信 缺货、严重预警 及时性强 成本高,信息不宜过长
企业微信/钉钉/飞书机器人 内部团队协作 接收率高,支持富文本 需要公司使用相应IM工具
系统后台站内信/通知中心 内部管理系统 与其他功能集成性好 依赖用户登录系统

高级优化与最佳实践

  1. 缓存库存值(Redis)

    • 对于高访问量的商品,库存每次从数据库读可能太慢。
    • 方案:库存主要存在 Redis 里(product_stock:123),出库时用 Redis 的 DECR 原子操作,然后异步同步回 MySQL。
    • 预警检查:可以在 Redis 里也存储一个阈值,触发 DECR 后比较,如果低于阈值,立即通知消息队列。
  2. 记录库存变更日志

    • 每次修改库存(增、减、手动调整)都应该记录到 stock_movements 表。
    • 作用:用于审计、追查“谁导致了预警”、分析历史库存趋势。
  3. 分级预警

    • 不仅设置一个阈值,可以设置多个等级。
    • warning_threshold = 50 (黄色预警,提示注意)
    • danger_threshold = 10 (红色预警,立即补货)
    • out_of_stock = 0 (严重,不能卖)
  4. 在订单流程中植入

    • 用户在后台或前台将商品加入购物车时,如果库存低于阈值,在商品页面上显示“库存紧张” 标签,这可以提升用户体验,并刺激用户尽快下单。
    • 实现:在展示商品详情时,执行一次比较。

一个可用的库存预警方案需要这三步:

  1. 数据准备:为每个商品配置不同的 low_stock_threshold,并设计好数据库索引。
  2. 逻辑触发:在每次库存变动后立即判断,并更新商品状态(正常/预警/缺货)。
  3. 通知落地:根据业务紧急程度,选择邮件、短信、IM机器人或系统内部通知。

如果你是开发中小型项目,从第二部分的定时任务 + 邮件通知开始做比较简单;如果是大型电商项目,建议直接上消息队列 + WebSocket + 实时日志的方案。

抱歉,评论功能暂时关闭!