从Meta API(WhatsApp Media)下载媒体文件时生成空文件的咨询
问题排查与解决方案
代码示例1的核心问题
- 同时启用
CURLOPT_FILE和CURLOPT_RETURNTRANSFER,这两个选项互斥:前者让curl直接把内容写入文件指针,后者让curl把内容返回给变量,导致逻辑混乱。 - 使用了未定义的
$response变量,substr($response, ...)会返回空值,写入文件自然为空。 - 在
curl_close($ch)之后调用curl_getinfo($ch),此时curl资源已销毁,无法获取正确的头部信息。
代码示例2的核心问题
- 重复设置
CURLOPT_FOLLOWLOCATION,虽不致命但属于冗余配置。 - 未检查curl执行结果是否成功:如果请求失败(比如令牌无效、URL过期),
$response会是false,写入文件后就是空文件。 - 未校验HTTP响应状态码:即使curl执行成功,也可能返回401(令牌错误)、404(媒体不存在)等错误状态,此时响应体不是文件内容。
修正后的完整代码
<?php $mediaId = "你的媒体ID"; $metaToken = "你的Meta授权令牌"; $url = "获取到的媒体URL"; $fileLoc = "./download/" . $mediaId . ".jpg"; // 确保下载目录存在 if (!is_dir("./download")) { mkdir("./download", 0755, true); } $ch = curl_init($url); $fp = fopen($fileLoc, 'wb'); curl_setopt_array($ch, [ CURLOPT_FILE => $fp, CURLOPT_TIMEOUT => 50, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . $metaToken ], CURLOPT_FAILONERROR => true // 遇到HTTP错误时直接返回false ]); $success = curl_exec($ch); if (!$success) { // 输出错误信息便于排查 echo "CURL错误: " . curl_error($ch); // 删除空文件 fclose($fp); unlink($fileLoc); } else { // 校验HTTP状态码是否为200 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($httpCode !== 200) { echo "HTTP错误: " . $httpCode; fclose($fp); unlink($fileLoc); } else { echo "文件下载成功"; fclose($fp); } } curl_close($ch); ?>
额外排查建议
- 确认
$metaToken(或$waToken)是有效的、具有whatsapp_business_messaging权限的令牌。 - 确认媒体URL未过期:WhatsApp Cloud API的媒体URL有效期为5分钟,过期后需要重新调用接口获取。
- 检查服务器是否能访问Meta的媒体服务器:可以用
curl -v "媒体URL" -H "Authorization: Bearer 你的令牌"在服务器终端测试,看是否返回文件内容。 - 确认
./download目录有写入权限:可以通过chmod 755 ./download设置权限。
内容的提问来源于stack exchange,提问作者izzymo
相关产品推荐
相关产品推荐

