【问题标题】:PHP - Can't post an image to my restful servicePHP - 无法将图像发布到我的宁静服务
【发布时间】:2014-08-23 20:51:03
【问题描述】:

我正在尝试使用 cURL 将图像发布到我的 RESTful 服务的图片上传方法。

restful 服务需要以下格式的请求:-

Accept: application/json
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

Content-Length: 782
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary5dQ1ta4rvOvWtjff

它还使用授权令牌字符串。

这是我的 PHP 代码:-

$_FILES['file'] 已作为 $data 传递给它,作为旁注。

move_uploaded_file($data["tmp_name"], "../uploaded_files/images/".$data["name"]);
$data_string = "@".realpath("../uploaded_files/images/".$data["name"]).";type=image/png";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CERTINFO, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

$boundary = md5(date('U'));
$http_headers = array(
    'Authorization: Bearer '.$_SESSION['Auth'],
    'Accept: application/json',
    'Accept-Encoding: gzip,deflate,sdch',
    'Content-Length: '.$data['size'],
    "Content-Type: multipart/form-data; boundary=$boundary"."\r\n"              
);

curl_setopt($ch, CURLOPT_HTTPHEADER, $http_headers);

$result = curl_exec($ch);
$info = curl_getinfo($ch);

据我所知,这应该匹配并且可以工作,但事实并非如此。当我包含 Content-Length 时(因为它是必需的,否则将生成 411 代码),服务器冻结,然后在很长一段时间后生成此错误:-

SSL read: error:00000000:lib(0):func(0):reason(0), errno 0

有谁知道我可能做错了什么?我能够使用上面的代码成功地发布 JSON 和其他内容类型,这似乎只是我试图以这种方式发布图像的特定方式。

编辑:我被告知文件上传的@方法已被弃用,所以我将我的代码调整为:-

$path = realpath("../upload_files/images/".$data["name"]);
$cfile = curl_file_create($path, 'image/png','file_upload');
$data_string = array('file_upload' => $cfile);

但是现在它会为“错误请求”生成 400 状态代码。我使用这种方法是错误的,还是我遗漏了什么?我也尝试过下面的面向对象版本,但它产生了同样的问题。

$cfile = new CURLFile($path,'image/png','file_upload');

【问题讨论】:

  • @filename 用于文件上传的 API 已弃用。您可以改用 CURLFile 类。
  • 我已经调整了代码以使用该类,但是现在我收到了代码 400 错误请求。
  • 调试CURL,看看发送了什么header/body。

标签: php rest curl


【解决方案1】:

问题很可能与您的请求的Content-Type 有关。判断给定的格式应该设置为multipart/form-data,即发送的数据应该编码为multipart/form-data。根据manual,为了将Content-Type 标头设置为multipart/form-data,您必须将CURLOPT_POSTFIELDS 选项设置为array(不是您的代码中的URL 编码字符串)。在这种情况下,数据将自动编码为multipart/form-data

所以你的代码应该是这样的:

move_uploaded_file($data["tmp_name"], "../uploaded_files/images/".$data["name"]);
$path = realpath("../uploaded_files/images/".$data["name"]);
$data = array('file' => "@$path;type=image/png");
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
...

顺便说一句: @ 前缀仅在 PHP 5.5.0 后被弃用。

【讨论】:

  • 内容类型设置为 multipart/form-data。我已经将 POSTfield 变量 ($data_string) 设置为一个数组,但是现在服务用代码 400: Bad Request 拒绝它,这对我来说没有任何意义。
  • 我发现了这个问题,它结合了 cURL 的编写方式,以及这个 RESTful API 服务是如何编写来解释所请求的标头的方法。我已经发布了一个详细说明这一点的答案。
【解决方案2】:

我在这里发现了问题。

我的 cURL 尝试连接的 restful 服务需要设置 Content Disposition 标头,cURL 故意忽略了这一点,因为它设置了自己的边界。

在这种情况下,使用 PHP 使用这个 API 的方法是不可能完成我想要做的事情的。

也就是说,除非有人知道可以设置内容配置的不同 php 库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多