如何使用Curl循环向从数据库获取号码的客户端发送数据?
我来帮你完善这个循环发送短信的功能,先指出原代码里的几个关键问题,再给出完整的可运行方案:
完整实现方案:用CURL循环向数据库获取的手机号发送短信
原代码的核心问题
- 使用了已废弃的
mysql_*函数:PHP 7及以上版本已经完全移除了这套函数,会导致运行报错,建议替换为mysqli或PDO - 变量引用错误:URL里的
$employee_salary应该是$employee_mobile,否则无法正确传递目标手机号 - CURL配置不完整:缺少执行请求、关闭资源和错误处理的逻辑,无法完成完整的请求流程
1. 基于MySQLi的完整实现(推荐)
先替换数据库连接逻辑,再完善CURL发送循环:
// 数据库连接配置 $dbHost = 'localhost'; $dbUser = '你的数据库用户名'; $dbPass = '你的数据库密码'; $dbName = '你的数据库名'; // 建立数据库连接 $conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName); if (!$conn) { die("数据库连接失败: " . mysqli_connect_error()); } // 从数据库获取短信内容(可根据实际业务逻辑调整获取方式) $text = "这是要发送的短信内容"; // 查询员工手机号(只查询需要的字段,提升性能) $sql = "SELECT employee_mobile FROM `employee`"; $result = mysqli_query($conn, $sql); // 短信API基础配置 $apiConfig = [ 'user' => 'MYUSERNAME', 'password' => 'MYPASSWORD', 'sid' => '78NSL', 'gwid' => 2 ]; // 循环处理每个手机号 if (mysqli_num_rows($result) > 0) { while($row = mysqli_fetch_assoc($result)) { $mobile = $row['employee_mobile']; // 跳过空手机号,避免无效请求 if (empty($mobile)) { echo "跳过空手机号<br>"; continue; } // 构建API请求参数,自动处理URL编码 $params = array_merge($apiConfig, [ 'msisdn' => $mobile, 'msg' => $text, 'fl' => 0 ]); $url = "http://mobile.ssexpertcompu.com/vendorsms/pushsms.aspx?" . http_build_query($params); // 初始化CURL $ch = curl_init(); // 设置CURL核心选项 curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 将结果返回而非直接输出 curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 请求超时时间 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 若API为HTTPS,生产环境建议开启验证 // 执行请求并获取响应 $response = curl_exec($ch); // 错误处理 if(curl_errno($ch)) { echo "发送失败给手机号 {$mobile}: CURL错误 - " . curl_error($ch) . "<br>"; } else { echo "请求已提交给手机号 {$mobile},API响应: {$response}<br>"; } // 关闭CURL资源 curl_close($ch); // 可选:添加1秒延迟,避免请求过于频繁触发API限流 sleep(1); } } else { echo "数据库中未找到有效员工手机号"; } // 关闭数据库连接 mysqli_close($conn);
2. 关键优化说明
- 用
http_build_query处理URL编码:比手动str_replace更可靠,能自动处理所有特殊字符(比如中文、空格等) - 新增空手机号过滤:避免向无效号码发送请求
- 完善错误处理:通过
curl_errno捕获CURL请求异常,便于排查问题 - 添加请求延迟:多数短信API有频率限制,
sleep(1)可以降低被限流的风险 - 只查询必要字段:替换
SELECT *为SELECT employee_mobile,减少数据库传输的数据量
3. 更灵活的PDO替代方案
如果需要兼容多种数据库,或者想使用预处理语句(养成安全编码习惯),可以用PDO实现数据库部分:
// PDO数据库连接 $dsn = "mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4"; $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]; try { $pdo = new PDO($dsn, $dbUser, $dbPass, $options); } catch(PDOException $e) { die("数据库连接失败: " . $e->getMessage()); } // 查询手机号 $stmt = $pdo->query("SELECT employee_mobile FROM employee"); while($row = $stmt->fetch()) { // 后续CURL发送逻辑和上面一致 }
内容的提问来源于stack exchange,提问作者andy
相关产品推荐
相关产品推荐

