PHP cURL上传BrickFTP时Content-Disposition头混入文件内容问题
解决PHP cURL上传文件到BrickFTP时Content-Disposition头混入文件内容的问题
嘿,我明白你现在遇到的麻烦——文件能成功上传到BrickFTP(实际存储在S3),但Content-Disposition头却跑到了文件内容的顶部,这肯定很闹心。我帮你梳理一下问题原因,再给出PHP cURL的正确实现方案。
问题根源
这种情况通常是因为你在构造上传请求时,错误地把HTTP头信息当成了文件内容的一部分,或者手动添加了Content-Disposition头,导致BrickFTP/S3把本该属于请求头的内容写入了文件本身。尤其是用multipart/form-data上传时,如果没有让cURL自动处理字段边界和头信息,很容易出现这个问题。
正确实现步骤
第一步:完成会话认证,获取有效Token
先完善你的认证代码,确保能拿到BrickFTP的会话Token,后续上传需要用这个Token做身份验证:
// 会话认证获取session token $ch = curl_init(); $postData = json_encode([ 'username' => 'xxx', 'password' => 'xxx' ]); curl_setopt($ch, CURLOPT_URL, "https://SUBDOMAIN.brickftp.com/api/rest/v1/sessions"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Accept: application/json' ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $sessionData = json_decode($response, true); $sessionToken = $sessionData['token']; // 提取会话Token
第二步:两种正确的上传方式
方式一:PUT直接上传二进制文件(推荐)
这种方式直接传输文件的二进制内容,不会混入多余的头信息,适合大部分场景:
$filePath = '/path/to/your/target-file.txt'; // 替换为你要上传到BrickFTP的目标路径 $uploadUrl = "https://SUBDOMAIN.brickftp.com/api/rest/v1/files/remote/path/to/target-file.txt"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $uploadUrl); curl_setopt($ch, CURLOPT_PUT, true); // 以二进制模式打开文件,避免编码问题 $fileHandle = fopen($filePath, 'rb'); curl_setopt($ch, CURLOPT_INFILE, $fileHandle); curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePath)); // 设置认证头和内容类型 curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: BrickAPI $sessionToken", 'Content-Type: application/octet-stream' // 明确二进制流类型 ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $uploadResponse = curl_exec($ch); fclose($fileHandle); curl_close($ch); // 检查上传结果 if ($uploadResponse === false) { echo "上传失败:" . curl_error($ch); } else { echo "文件上传成功!"; }
方式二:Multipart/form-data上传
如果需要附带其他表单字段,可以用这种方式,但一定要用CURLFile类让cURL自动处理文件上传的头信息:
$filePath = '/path/to/your/target-file.txt'; // 替换为BrickFTP的目标目录路径 $uploadUrl = "https://SUBDOMAIN.brickftp.com/api/rest/v1/files/remote/directory/path"; $ch = curl_init(); // 用CURLFile构造文件字段,cURL会自动处理Content-Disposition等头 $postFields = [ 'file' => new CURLFile( $filePath, mime_content_type($filePath), // 自动获取文件MIME类型 basename($filePath) // 上传后的文件名 ) ]; curl_setopt($ch, CURLOPT_URL, $uploadUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: BrickAPI $sessionToken", 'Accept: application/json' ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $uploadResponse = curl_exec($ch); curl_close($ch);
要避免的错误写法
千万不要手动把Content-Disposition头拼接到文件内容里,比如这种错误示例:
// 错误!会把头信息写入文件内容 $fileContent = "Content-Disposition: attachment; filename=\"file.txt\"\r\n\r\n" . file_get_contents($filePath); curl_setopt($ch, CURLOPT_POSTFIELDS, $fileContent);
按照上面的正确方式实现,应该就能解决Content-Disposition头混入文件内容的问题了。
内容的提问来源于stack exchange,提问作者Morgan
相关产品推荐
相关产品推荐

