You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PHP高效发送大量GET请求?批量短信模块开发疑问

解决PHP短信群发效率问题的实用方案

嘿,针对你开发的PHP管理员短信跟进模块在批量发送时遇到的效率瓶颈,我整理了几个实战中好用的解决思路:

1. 用Curl并行请求替代同步的file_get_contents

file_get_contents是同步阻塞的——发一条短信就得等请求完成才能发下一条,批量发送时效率极低。改用curl_multi系列函数实现并行请求,能同时发起多个API调用,大幅缩短总耗时。

举个简单的示例代码:

// 待发送的手机号列表
$phoneNumbers = ['138xxxxxxx', '139xxxxxxx', ...];
$message = "你的跟进短信内容";
$apiUrl = "sms_api_url?credentials&phone=%s&msg=%s";

// 初始化curl多句柄
$mh = curl_multi_init();
$handles = [];

foreach ($phoneNumbers as $phone) {
    $url = sprintf($apiUrl, urlencode($phone), urlencode($message));
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_multi_add_handle($mh, $ch);
    $handles[] = $ch;
}

// 执行并行请求
$running = null;
do {
    curl_multi_exec($mh, $running);
    curl_multi_select($mh);
} while ($running > 0);

// 处理结果并清理句柄
foreach ($handles as $ch) {
    $response = curl_multi_getcontent($ch);
    // 这里可以记录发送结果(成功/失败)
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}
curl_multi_close($mh);

2. 优先使用API的批量发送接口(如果支持)

先去查一下你用的短信API文档,看看有没有批量发送的接口——比如允许一次传入多个手机号(用逗号分隔或者数组参数),这样只需要发起1次请求就能完成多条短信发送,效率提升是数量级的。这是最优解,比任何客户端优化都管用。

3. 引入队列系统处理超大量发送

如果要发送几百甚至上千条短信,直接在Web请求里处理很容易超时,还会影响用户体验。建议用队列异步处理:

  • 第一步:把需要发送的手机号、消息内容存入队列(比如用Redis队列,或者数据库表作为简易队列)
  • 第二步:写一个CLI脚本(命令行运行的PHP脚本),后台循环从队列里取出任务,逐条/批量发送
  • 额外好处:可以轻松实现失败重试、发送进度统计,还能避免Web请求超时

简易数据库队列示例:

// 存入队列(Web端调用)
$pdo = new PDO('mysql:host=localhost;dbname=your_db', 'user', 'pass');
$sql = "INSERT INTO sms_queue (phone, message, status) VALUES (?, ?, 'pending')";
$stmt = $pdo->prepare($sql);
foreach ($phoneNumbers as $phone) {
    $stmt->execute([$phone, $message]);
}

// 消费队列的CLI脚本
while (true) {
    $stmt = $pdo->query("SELECT * FROM sms_queue WHERE status='pending' LIMIT 10 FOR UPDATE");
    $tasks = $stmt->fetchAll(PDO::FETCH_ASSOC);
    if (empty($tasks)) {
        sleep(5); // 没有任务就休眠5秒再查
        continue;
    }
    // 这里用curl_multi批量处理这10条任务
    // ...(参考上面的curl_multi代码)
    // 更新任务状态为success/failed
    foreach ($tasks as $task) {
        $updateStmt = $pdo->prepare("UPDATE sms_queue SET status=? WHERE id=?");
        $updateStmt->execute([$sendResult ? 'success' : 'failed', $task['id']]);
    }
}

4. 小幅度优化file_get_contents(应急方案)

如果暂时不想换Curl,可以通过修改流上下文参数来优化file_get_contents的性能,比如缩短超时时间、开启持久连接:

$context = stream_context_create([
    'http' => [
        'timeout' => 5, // 设置5秒超时,避免长时间等待
        'keep_alive' => true, // 开启持久连接
    ]
]);
$result = file_get_contents($url, false, $context);

不过这个优化的效果有限,只适合小批量发送的场景。

额外注意事项

  • 务必查看短信API的频率限制:很多API会限制单位时间内的请求次数,别因为批量发送触发限流导致失败
  • 跨域问题:虽然你用GET请求测试正常,但批量发送时要确保API服务器允许你的域名发起大量请求,避免被跨域策略拦截

内容的提问来源于stack exchange,提问作者Danish Nayeem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:25:17