Imgur API PHP视频上传报错求助:无法发送视频数据
Fixing Imgur API Video Upload Failures in PHP
我帮你梳理了代码和遇到的问题,核心是视频上传时没有正确把文件数据传递给Imgur API,同时还有未处理请求失败的情况导致的Undefined Index错误,以及大文件上传的超时问题。咱们一步步来解决:
1. 用CURLFile代替手动二进制读取(关键修复)
你之前用fread读取二进制数据放到POST字段里的方式,对小体积的图片/GIF可能巧合生效,但视频体积大,这种方式不符合cURL处理文件上传的规范。Imgur API要求文件以二进制形式上传,PHP 5.5+之后推荐用CURLFile类来处理,它会自动帮你处理文件的MIME类型和上传格式,完美适配Imgur的要求。
修改你的POST字段部分:
// 自动判断文件类型,决定用image还是video字段 $fileField = str_starts_with($_FILES["imglink"]["type"], 'video/') ? 'video' : 'image'; CURLOPT_POSTFIELDS => array( $fileField => new CURLFile($fileTmpName, $_FILES["imglink"]["type"], $fileName), "type" => "file", "title" => $title, "description" => $desc, ),
- 不用再手动读文件二进制内容,
CURLFile会直接从临时文件路径读取并正确上传。 - 自动切换
image/video字段,避免手动判断出错。
2. 修复Undefined Index: link错误
当请求失败时,$pms['data']['link']根本不存在,直接访问就会报索引未定义的错误。先检查请求是否成功,再去取返回的链接:
$pms = json_decode($response, true); // 先判断API请求是否成功 if ($pms['success'] === true) { $url = $pms['data']['link']; echo "Posted"; // 对URL做编码,避免特殊字符导致跳转失败 header("location: ../sub-pages/succes.php?link=". urlencode($url)); exit; // 跳转后一定要exit,防止后续代码继续执行 } else { echo "<h2>There's a Problem</h2>"; // 安全输出错误信息,避免索引不存在的问题 echo isset($pms['data']['error']) ? $pms['data']['error'] : 'Unknown error occurred'; }
3. 解决视频上传超时问题
视频文件体积通常较大,默认的cURL超时设置可能不够用。调整超时参数,给足够的时间让文件上传完成:
CURLOPT_TIMEOUT => 300, // 设置为300秒(5分钟),根据你常传的视频大小调整 CURLOPT_CONNECTTIMEOUT => 10, // 连接超时设为10秒,避免长时间等待无效连接
- 不要用
CURLOPT_TIMEOUT => 0,某些服务器环境下可能导致异常,明确设置一个合理的大值更稳妥。 - 同时检查你的PHP配置:确保
upload_max_filesize和post_max_size的值足够大(比如设为200M,对应Imgur的最大视频限制),可以在php.ini里修改,或者用.htaccess配置。
4. 清理多余的cURL选项
你的代码里有些重复或不必要的选项,可能干扰请求:
- 移除
CURLOPT_CUSTOMREQUEST => "POST",因为已经设置了CURLOPT_POST => 1,重复设置可能导致请求格式异常。 - 把
CURLOPT_FOLLOWLOCATION设为true,如果Imgur API有跳转的话能正确跟随(虽然API一般不会跳转,但开启更稳妥)。 - 测试环境结束后,把
CURLOPT_SSL_VERIFYHOST和CURLOPT_SSL_VERIFYPEER改回默认的安全值(2和true),不要一直关闭SSL验证,避免安全风险。
完整修改后的核心代码片段
// 表单提交内容 $title = htmlspecialchars($_POST["title"]); $posted = htmlspecialchars($_POST["token"]); $desc = htmlspecialchars($_POST["desc"]); // 表单文件数据 $fileName = $_FILES["imglink"]["name"]; $fileTmpName = $_FILES["imglink"]["tmp_name"]; $fileType = $_FILES["imglink"]["type"]; $size = $_FILES["imglink"]["size"]; // 检查参数是否齐全 if ($title != "" && $desc != "" && is_string($posted)) { if(empty($fileName)){ header("location: ../sub-pages/error.php?noimage"); exit; // 跳转后终止代码执行 }else{ // 判断文件类型对应的API字段 $fileField = str_starts_with($fileType, 'video/') ? 'video' : 'image'; // 初始化cURL请求 $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_URL => "https://api.imgur.com/3/upload", CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_ENCODING => "", CURLOPT_POST => 1, CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 300, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_POSTFIELDS => array( $fileField => new CURLFile($fileTmpName, $fileType, $fileName), "type" => "file", "title" => $title, "description" => $desc, ), CURLOPT_HTTPHEADER => array( "Authorization: Bearer ". $posted), )); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); // 先处理cURL本身的错误 if ($err) { echo "<h2>CURL Error</h2>"; echo $err; exit; } $pms = json_decode($response, true); // 处理API响应 if ($pms['success'] === true) { $url = $pms['data']['link']; echo "Posted"; header("location: ../sub-pages/succes.php?link=". urlencode($url)); exit; } else { echo "<h2>There's a Problem</h2>"; echo isset($pms['data']['error']) ? $pms['data']['error'] : 'Unknown error occurred'; } } } else{ echo "Missing required parameters"; }
额外注意事项
- 确认你的Imgur API令牌有视频上传权限,某些令牌可能仅限制图片上传。
- 检查视频的格式和大小是否符合Imgur的要求:最大支持200MB,格式限MP4、MOV等(具体看Imgur官方文档)。
- 测试时可以用
var_dump($response)查看完整的API返回,方便排查问题。
内容的提问来源于stack exchange,提问作者Heakter




