php - 上传的文件在 guzzle json_encode 错误中使用 fopen 错误打开:不支持类型
问题描述
我无法附加上传的文件。我看到 fopen($image->getPathname(),'r') 返回不可转换的 json 数据类型,使 guzzle 返回错误 json_encode 错误:不支持类型。我在这里做错了什么?谢谢你。
stream resource @586 ▼
timed_out: false
blocked: true
eof: false
wrapper_type: "plainfile"
stream_type: "STDIO"
mode: "r"
unread_bytes: 0
seekable: true
uri: "\Temp\php2D41.tmp"
options: []
//use Illuminate\Support\Facades\Http;
//use Illuminate\Support\Facades\File;
if($request->hasFile('imgInp1'))
{
foreach(request('imgInp1') as $image)
{
$message = Http::post('https://graph.facebook.com/v9.0/me/message_attachments?access_token='.$access_token,
[
'headers' => [
'Content-Type' => 'multipart/form-data',
],
'multipart' => [
'name' => 'image',
'image_path' => $image->getPathname(),
'image_mime' => $image->getmimeType(),
'image_org' => $image->getClientOriginalName(),
'contents' => fopen($image->getPathname(), 'r'),
],
'message'=>[
'attachment' => [
'type' => 'image',
'payload' => [
"is_reusable"=> true,
],
],
],
]);
}
}
解决方案
从您使用的 url,这是 facebook api_guide中提供的 curl 请求
curl \
-F 'message={"attachment":{"type":"image", "payload":{"is_reusable":true}}}' \
-F 'filedata=@/tmp/shirt.png;type=image/png' \
"https://graph.facebook.com/v9.0/me/message_attachments?access_token=<PAGE_ACCESS_TOKEN>"
这就是 -F 在 curl 中的含义
-F, --form <name=content>
(HTTP SMTP IMAP) 对于 HTTP 协议族,这让 curl 模拟一个用户按下提交按钮的填充表单。这会导致 curl 根据 RFC 2388 使用 Content-Type multipart/form-data 发布数据。
(来源man curl
:)
通过解释卷曲的第二行,
您还可以通过使用 'type=' 告诉 curl 要使用的 Content-Type,其方式类似于:
curl -F "web=@index.html;type=text/html" example.com
或
curl -F "name =daniel;type=text/foo" example.com
所以它告诉你需要多部分/表单数据。
我直接使用 guzzle 代替使用 HttpClient(在 laravel 中默认提供,来自 composer.json 的确认)。另外我建议使用 try catch 块,因为它不一定总是 200 响应。
$message["attachment"] = [
"type" => "image",
"payload"=> ["is_reusable"=>true]
];
try{
$client = new \GuzzleHttp\Client();
if(file_exists($image)){ // or can use \Illuminate\Support\Facades\File::exists($image)
$request = $client->post( 'https://graph.facebook.com/v9.0/me/message_attachments?access_token='.$access_token, [
// 'headers' => [], //if you want to add some
'multipart' => [
[
'name' => 'message',
'contents' => json_encode($message),
],
[
'Content-type' => $image->getmimeType(),
'name' => 'filedata',
'contents' => fopen($image->getPathname(), 'r'),
]
]
]);
if ($request->getStatusCode() == 200) {
$response = json_decode($request->getBody(),true);
//perform your action with $response
}
}else{
throw new \Illuminate\Contracts\Filesystem\FileNotFoundException();
}
}catch(\GuzzleHttp\Exception\RequestException $e){
// see this answer for https://stackoverflow.com/questions/17658283/catching-exceptions-from-guzzle/64603614#64603614
// you can catch here 400 response errors and 500 response errors
// see this https://stackoverflow.com/questions/25040436/guzzle-handle-400-bad-request/25040600
}catch(Exception $e){
//catch other errors
}
推荐阅读
- swift - 具有关联类型的 Swift 协议:如何在抽象方法中使用?
- python - 如何使用多线程加速嵌套for循环计算?
- firefox - 使用 FireFox 和 HTTP(S) 测试脚本记录器时的 JMeter“内容编码错误”
- r - 正则表达式在 R 中提取特定域名
- android - 了解有无 SurfaceHolder.Callback 的 SurfaceView
- php - 问题 PHP MARIADB PHPMYADMIN 使用 docker-compose
- erlang - 使用重复生成变化 Erlang
- logstash - 如何获取使用 Logstash Container 运行应用程序生成的日志[数据]
- c# - “WireUpCoreRuntime”任务意外失败 Visual Studio 2017
- angularjs - 删除循环中的项目并添加新数组