如何用PHP实现MySQL广告表逗号分隔用户ID列表更新与唯一点击统计
实现方案(适配PHP7.3)
注:当前用逗号拼接存储用户ID的方案仅适合小体量数据场景,若广告点击量过万建议后续单独建
ad_click_rel关联表存储广告ID和用户ID的对应关系,查询、维护效率会高很多。
前置准备
提前替换代码中的以下配置项:
- 数据库连接参数(host、库名、用户名、密码)
- 广告ID获取逻辑(一般从用户点击的请求参数中取,需校验为正整数)
- 当前登录用户ID获取逻辑(一般从session或登录态中取,需校验为正整数)
- 邮件发送逻辑可根据实际业务替换
方案1:PHP层面判断(逻辑直观,适合新手理解)
<?php // 1. 初始化PDO数据库连接 $dbHost = '127.0.0.1'; $dbName = '你的库名'; $dbUser = '数据库用户名'; $dbPass = '数据库密码'; $pdo = new PDO("mysql:host={$dbHost};dbname={$dbName};charset=utf8mb4", $dbUser, $dbPass); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 2. 获取并校验参数 $adId = (int)$_GET['ad_id']; // 示例:从请求参数中取广告ID $currentUserId = (int)$_SESSION['user_id']; // 示例:从session中取当前登录用户ID if ($adId <= 0 || $currentUserId <= 0) { die('参数非法'); } // 3. 查询对应广告的已点击用户ID列表 $stmt = $pdo->prepare("SELECT item_discount_userid FROM ads WHERE id = ?"); $stmt->execute([$adId]); $useridStr = $stmt->fetchColumn(); // 4. 判断当前用户是否已点击 $userIdArr = $useridStr === '' ? [] : explode(',', $useridStr); if (!in_array((string)$currentUserId, $userIdArr, true)) { // 5. 未点击则追加用户ID更新到数据库 $newUseridStr = $useridStr === '' ? (string)$currentUserId : $useridStr . ',' . $currentUserId; $updateStmt = $pdo->prepare("UPDATE ads SET item_discount_userid = ? WHERE id = ?"); $updateStmt->execute([$newUseridStr, $adId]); // 6. 触发邮件发送逻辑 $to = '用户邮箱地址'; // 从用户信息中取 $subject = '广告点击通知'; $content = '你已成功点击广告'; $headers = 'From: admin@你的域名.com' . "\r\n" . 'Reply-To: admin@你的域名.com' . "\r\n" . 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $content, $headers); }
方案2:SQL层面直接判断(性能更高,减少并发冲突)
无需先查询再判断,直接通过UPDATE语句的条件判断是否需要更新,可减少一次数据库查询,同时降低并发场景下重复写入的概率:
<?php // 1. 初始化PDO连接、参数校验逻辑和方案1一致,此处省略 // ... 省略重复代码 ... // 2. 直接执行UPDATE,仅当用户ID不存在时才更新 $updateStmt = $pdo->prepare("UPDATE ads SET item_discount_userid = IF( item_discount_userid = '', ?, CONCAT(item_discount_userid, ',', ?) ) WHERE id = ? AND FIND_IN_SET(?, item_discount_userid) = 0"); $updateStmt->execute([$currentUserId, $currentUserId, $adId, $currentUserId]); // 3. 若更新行数大于0,说明是首次点击,触发邮件发送 if ($updateStmt->rowCount() > 0) { // 邮件发送逻辑和方案1一致,此处省略 // ... 省略邮件代码 ... }
内容的提问来源于stack exchange,提问作者user9142657
相关产品推荐
相关产品推荐

