php - 使用 CURL 上传给定的文件和 POST-Date
问题描述
也许有人可以帮助我?我没有解决这个问题
我有一个来自公式的 POST 数组和一个已经存在于服务器上的文件。任务是通过 CURL PUT 将 POST 数据和文件发送到 URL。
我已经尝试解决这个问题几个小时/几天了
我已经设置了标题Content-type: application/octet-stream
和字段$ch->setOption(CURLOPT_POSTFIELDS, http_build_query($data)
POST 数据如下所示:
$data = array (
'field1' => 'lorem',
'field2' => 'ipsum',
'field3' => 'dolor'
);
使用说明(php.net、stackoverflow 等)
https://kb.detlus.com/articles/php/upload-files-using-curl/
https://www.php.net/manual/de/curlfile.construct.php
我尝试发送文件
不工作
$data = array (
'field1' => 'lorem',
'field2' => 'ipsum',
'field3' => 'dolor'
'file' => '@'.realpath('/abs/path/file.xlsx');
);
两者都不
$data = array (
'field1' => 'lorem',
'field2' => 'ipsum',
'field3' => 'dolor'
);
$data['file'] = curl_file_create('/abs/path/file.xlsx'], mime_content_type('/abs/path/file.xlsx'), 'file.xlsx');
这导致以下数组
$data = array (
'field1' => 'lorem',
'field2' => 'ipsum',
'field3' => 'dolor',
'file' =>
array (
'file' =>
CURLFile::__set_state(array(
'name' => '/abs/path/file.xlsx',
'mime' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'postname' => '/abs/path/file.xlsx',
)),
)
);
根据我尝试的版本,我会收到 400 或 500 错误。
有没有人有可以帮助我的提示?我究竟做错了什么?
解决方案
I think the main problem here is that you're using the wrong content type.
For file uploads you should be using "Content-Type: multipart/form-data". Taken from Wikipedia (in the multipart subtypes) MIME
The MIME type multipart/form-data is used to express values submitted through a form. Originally defined as part of HTML 4.0, it is most commonly used for submitting files with HTTP. It is specified in RFC 7578, superseding RFC 2388.
I wrote this snippet, hope this can help you (sorry for the non-OOP version of the code, I don't have a PHP 8 install, I'm using PHP 7.4, but you can "translate" it easily :D):
<?php
//This is a dummy data array, will contain your form fields (Advice: never trust user input, always check the values given before submitting)
$data = [
'field1' => 'value',
'field2' => 'value2',
'field3' => 123
];
//The path to the file you want to upload
$fileName = 'somefile.xlsx';
$filePath = './../files/'.$fileName;
//Security check
if (file_exists($filePath))
{
//Adding the file to the $data array
$data['file'] = curl_file_create($filePath, mime_content_type($filePath), $fileName);
//Initialize the cURL handle
$ch = curl_init('https://some-random-site.com/api/some/random/endpoint');
//Set the request method (HTTP verb)
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
//This will make curl "return" the response as string when we call curl_exec()
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//This SHALL NOT be used in production, unless you know the implications!!! But, if you have an HTTPS endpoint with a self-signed certificate you can skip checks
//curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//======
//We set the data we want to send (curl will "transform" this for us
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
//Here the important part, setting the right content-type
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: multipart/form-data']);
//Execute the call and get the response as string
$res = curl_exec($ch);
if ($res === false)
{
//An error occurred, print out
echo 'ERROR: '.curl_error($ch);
}
else
{
//Execution succeeded, do whatever with the response
//Hint: this does not mean that the server answered with a success status but rather, it indicates that the curl execution has succeeded
//If you want to check the HTTP status of the request you can get it like this:
//$info = curl_getinfo($curl);
//echo $info['http_code'];
//Do whatever with the response (I'm just printing it).
echo $res;
}
curl_close($ch);
}
else
{
echo 'File not found.';
}
I really hope this can help, unfortunately I don't know the URL/API you're submitting the request to so I can't test it on your endpoint. I made an endpoint myself:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'PUT')
{
$c = file_get_contents('php://input');
die(var_dump($c));
}
The output I got showed me all the fields and the file upload.
--------------------------05a7619c906d94df Content-Disposition: form-data; name="field1" value
--------------------------05a7619c906d94df Content-Disposition: form-data; name="field2" value2
--------------------------05a7619c906d94df Content-Disposition: form-data; name="field3" 123
--------------------------05a7619c906d94df Content-Disposition: form-data; name="file"; filename="./../conf/test.xlsx" Content-Type:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
........LOTS_OF_BYTES_OF_THE_XLSX_FILE_:P......
--------------------------05a7619c906d94df--
推荐阅读
- javascript - 仅使用类的一部分声明变量
- azure - 从 VSTS 获取 Azure AD 访问令牌?
- python - 从熊猫数据框制作字典
- postgresql - sql 脚本是仅由 PostgreSQL 服务器接受,还是由服务器和客户端 psql 接受?
- c# - JsonConvert SerializeObject 未正确序列化字符串数组
- github - 如何在 GitHub Pages 上的根域和 WWW 子域上强制执行 HTTPS?
- vb.net - 如何确保在模拟中使用唯一的随机数?
- marklogic - system_time 大于当前日期时间
- javascript - 如何将一个jsp页面显示为另一个jsp页面中的弹出窗口
- python-3.x - 将数据组织到嵌套字典中:错误“列表索引必须是整数或切片,而不是 str”