Php Guzzle 6:上载带有阵列数据的文件
我必须用文件发送数组数据。仅使用数据即可正常工作:Php Guzzle 6:上载带有阵列数据的文件,php,arrays,guzzle6,Php,Arrays,Guzzle6,我必须用文件发送数组数据。仅使用数据即可正常工作: $client->post('http://xxx/', [ 'form_params' => [ [ 'data' => ['id' => 1234, 'name' => 'nombre'], 'valid' => true ] ] ]); 但是,既然我不能将“form_params”与“multipart”一
$client->post('http://xxx/', [
'form_params' => [
[
'data' => ['id' => 1234, 'name' => 'nombre'],
'valid' => true
]
]
]);
但是,既然我不能将“form_params”与“multipart”一起使用,那么如何发送带有数组和布尔数据的文件呢
我试过:
$client->post('http://xxx/', [
'multipart' => [
[
'name' => 'myfile',
'contents' => fopen('my_file.txt', 'r'),
],
[
'name' => 'data',
'contents' => ['id' => 1234, 'name' => 'nombre'],
]
[
'name' => 'valid',
'contents' => true,
]
],
]);
但我得到一个错误,因为“内容”不接受布尔值或数组值
我需要一些帮助
谢谢
更新:
我无法解决这个问题,最后我不得不使用一个不太好的解决方案,包括作为查询字符串的form field参数和使用Multipart。比如:
$client->post('http://xxx?id=1234&name=nombre', [
'multipart' => [
[
'name' => 'myfile',
'contents' => fopen('my_file.txt', 'r'),
],
],
])) 根据Guzzle文件: multipart的值是关联数组的数组,每个数组 包含以下键值对:
- 名称:(字符串,必填)表单字段名称
- 内容:(StreamInterface/resource/string,必选)要在表单元素中使用的数据
- Header:(数组)可选的自定义标题关联数组,用于表单元素
- filename:(string)作为部件中的文件名发送的可选字符串
$client->post('http://xxx/', [
'multipart' => [
[
'name' => 'myfile',
'contents' => fopen('my_file.txt', 'r'),
],
[
'name' => 'id',
'contents' => '1234',
],
[
'name' => 'name',
'contents' => 'nombre',
],
[
'name' => 'valid',
'contents' => 'true',
]
],
]);
在不知道如何解析数据的情况下,我无法确定这是否是一个可行的选项,但由于它接受自定义标题,因此可以将其作为JSON数组(字符串形式)发送,然后设置内容类型:
$client->post('http://xxx/', [
'multipart' => [
[
'name' => 'myfile',
'contents' => fopen('my_file.txt', 'r'),
],
[
'name' => 'data',
'contents' => '{"id":1234, "name":"nombre"}',
'headers' => ['Content-Type' => 'text/x-json']
],
[
'name' => 'valid',
'contents' => 'true',
]
],
]);
另一个选择是直接使用cURL,尽管我确信您希望避免这种情况,因为您使用的是Guzzle
更新
这不是我个人测试过的东西,但这里还有一件事你可以试试。。。(其实我应该先想到这一点)
根据Guzzle文件: multipart的值是关联数组的数组,每个数组 包含以下键值对:
- 名称:(字符串,必填)表单字段名称
- 内容:(StreamInterface/resource/string,必选)要在表单元素中使用的数据
- Header:(数组)可选的自定义标题关联数组,用于表单元素
- filename:(string)作为部件中的文件名发送的可选字符串
$client->post('http://xxx/', [
'multipart' => [
[
'name' => 'myfile',
'contents' => fopen('my_file.txt', 'r'),
],
[
'name' => 'id',
'contents' => '1234',
],
[
'name' => 'name',
'contents' => 'nombre',
],
[
'name' => 'valid',
'contents' => 'true',
]
],
]);
在不知道如何解析数据的情况下,我无法确定这是否是一个可行的选项,但由于它接受自定义标题,因此可以将其作为JSON数组(字符串形式)发送,然后设置内容类型:
$client->post('http://xxx/', [
'multipart' => [
[
'name' => 'myfile',
'contents' => fopen('my_file.txt', 'r'),
],
[
'name' => 'data',
'contents' => '{"id":1234, "name":"nombre"}',
'headers' => ['Content-Type' => 'text/x-json']
],
[
'name' => 'valid',
'contents' => 'true',
]
],
]);
另一个选择是直接使用cURL,尽管我确信您希望避免这种情况,因为您使用的是Guzzle
更新
这不是我个人测试过的东西,但这里还有一件事你可以试试。。。(其实我应该先想到这一点)
有一个选项可以通过Guzzle将上传文件和阵列数据一起发送,但形式有所改变:
$client->post('http://xxx/', [
'multipart' => [
[
'name' => 'myfile',
'contents' => fopen('my_file.txt', 'r'),
],
[
'name' => 'data[0][id]',
'contents' => 1234,
],
[
'name' => 'data[0][name]',
'contents' => 'nombre',
],
[
'name' => 'data[1][id]',
'contents' => 2222,
],
[
'name' => 'data[1][name]',
'contents' => 'nombre2',
],
[
'name' => 'valid',
'contents' => true,
]
],
]);
另一方面,您可以使用$\u POST['data']
获取数据,然后执行foreach:
foreach ($_POST['data'] as $data) {
echo "Id: ".$data['id'];
echo "Name: ".$data['name'];
}
有一个选项可以通过Guzzle将上传文件和阵列数据一起发送,但形式有所改变:
$client->post('http://xxx/', [
'multipart' => [
[
'name' => 'myfile',
'contents' => fopen('my_file.txt', 'r'),
],
[
'name' => 'data[0][id]',
'contents' => 1234,
],
[
'name' => 'data[0][name]',
'contents' => 'nombre',
],
[
'name' => 'data[1][id]',
'contents' => 2222,
],
[
'name' => 'data[1][name]',
'contents' => 'nombre2',
],
[
'name' => 'valid',
'contents' => true,
]
],
]);
另一方面,您可以使用$\u POST['data']
获取数据,然后执行foreach:
foreach ($_POST['data'] as $data) {
echo "Id: ".$data['id'];
echo "Name: ".$data['name'];
}
可以使用递归方法获取数据数组并准备多部分数组:
private function prepareMultipartParams($params, $baseKey = null): array
{
$result = [RequestOptions::MULTIPART => []];
foreach ($params as $key => $value) {
$key = $baseKey == null ? $key : "{$baseKey}[{$key}]";
if (is_array($value))
foreach ($this->prepareMultipartParams($value, $key) as $array)
$result[RequestOptions::MULTIPART] = array_merge($result[RequestOptions::MULTIPART], $array);
else
$result[RequestOptions::MULTIPART][] = [
'name' => $key,
'contents' => $value instanceof UploadedFile ? fopen($value->path(), 'r+') : $value
];
}
return $result;
}
可以使用递归方法获取数据数组并准备多部分数组:
private function prepareMultipartParams($params, $baseKey = null): array
{
$result = [RequestOptions::MULTIPART => []];
foreach ($params as $key => $value) {
$key = $baseKey == null ? $key : "{$baseKey}[{$key}]";
if (is_array($value))
foreach ($this->prepareMultipartParams($value, $key) as $array)
$result[RequestOptions::MULTIPART] = array_merge($result[RequestOptions::MULTIPART], $array);
else
$result[RequestOptions::MULTIPART][] = [
'name' => $key,
'contents' => $value instanceof UploadedFile ? fopen($value->path(), 'r+') : $value
];
}
return $result;
}
非常感谢@Jabari,您的第一个选项是不可能的,因为我需要发送一个带有“数据”键的数组,第二个我已经尝试过了,第三个不起作用。唯一的可能是发送“form_param”选项。。。有没有办法在“form_params”选项中发送文件?谢谢again@Averias今天晚些时候我会做一些测试,我也很想让它工作。非常感谢@Jabari,您的第一个选项不可能,因为我需要发送一个带有“数据”键的数组,第二个我已经尝试过了,第三个不起作用。唯一的可能是发送“form_param”选项。。。有没有办法在“form_params”选项中发送文件?谢谢again@Averias今天晚些时候我会做一些测试,我也很想让它正常工作。我自己也在解决这个问题。我通过设置[headers]=>[[Content Type]=>application/x-www-form-urlencoded]获得了数组数据。但是我无法获得一个文件来传递这些数据。把这个关于数组的问题看作是内容的值,我自己也在解决这个问题。我通过设置[headers]=>[[Content Type]=>application/x-www-form-urlencoded]获得了数组数据。但是我无法获得一个文件来传递这些数据。请看这期关于数组作为内容值的文章,太棒了,谢谢!太棒了,谢谢!