带有文件附件的PHP Curl发布;自定义内容类型标题 [英] PHP Curl post with file attachment; custom content-type header

查看:106
本文介绍了带有文件附件的PHP Curl发布;自定义内容类型标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须将文件连同一些发布参数一起发布到服务器.我从该服务器管理员那里收到的文档显示了发布请求的外观示例( * 注意POST"multipart/x-api-remote-integration"的自定义内容类型) :

I have to post a file to a server along side with a few post params. The documentation I received from this server admin shows an example of what the post request is supposed to look like (* NOTE the custom content type for the POST "multipart/x-api-remote-integration"):

POST /gateway/remote_send HTTP/1.0

Content-Type: multipart/x-api-remote-integration; boundary=ABC1234

Content-Length: 323

--ABC1234

Content-Type: application/x-www-form-urlencoded

profile_name=username&profile_pw=password1234&attached_type=action_1

--ABC1234

Content-Type: text/csv

Content-Disposition: attachment; filename="attachment.csv"
row1
row2
row3

--ABC1234--

以下是php代码:

<?php
function post(){
    $base_api_url = "https://hostserver.com/gateway/remote_send";

    $filename = realpath("/home/username/tests/test1234qwerty.csv");

    $payload['profile_name'] = "username";
    $payload['profile_pw'] = 'password1234';
    $payload['attached_type'] = 'action_1';
    $payload['filename'] = "@" . $filename . ";type=text/csv;";

    $curl_options = array(
        CURLOPT_URL => $base_api_url,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query( $payload ),
        CURLOPT_HTTP_VERSION  => 1.0,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_VERBOSE => true,
        CURLOPT_HEADER => false,
    );

    $curl = curl_init();
    curl_setopt_array( $curl, $curl_options );
    $result = curl_exec( $curl );
    curl_close ($curl);
    echo $result;
  }

post();

从我从服务器收到的回信中,似乎已正确接收了发件人字段.但是,该文件未被接收.我不确定自己做错了什么.任何输入,我们将不胜感激.

From what I am receiving back from the server, it seems that the post fields are being received properly. However it's the file that is not being received. I'm not sure what I did wrong. Any input is greatly appreciated.

附加详细响应:

* About to connect() to hostserver.com port 443 (#0)
*   Trying x.x.x.x... * connected
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSL connection using DHE-RSA-AES256-SHA
*   ******** REDACTED ************
*   SSL certificate verify ok.
> POST /gateway/remote_send HTTP/1.0
Host: hostserver.com
Accept: */*
Content-Length: 110
Content-Type: application/x-api-remote-integration

* upload completely sent off: 110out of 110 bytes
< HTTP/1.1 200 OK
< Date: Mon, 19 Aug 2013 16:00:38 GMT
< Server: Apache/2.2.15 (Red Hat)
< Pragma: no-cache
< CacheControl: no-cache
< Cache-Control: no-cache
< Expires: -1
< Connection: close
< Content-Type: multipart/x-api-remote-integration; boundary=remote_send-52124126
<
* Closing connection #0
HTTP/1.1 200 OK
Date: Mon, 19 Aug 2013 16:00:38 GMT
Server: Apache/2.2.15 (Red Hat)
Pragma: no-cache
CacheControl: no-cache
Cache-Control: no-cache
Expires: -1
Connection: close
Content-Type: multipart/x-vcg-remote-api; boundary=remote_send-52124126

--remote_send-52124126
Content-Type: application/x-www-form-urlencoded

result=invalid_filename
--remote_send-52124126--

我知道用户名和密码数据已由服务器正确读取,因为我已经测试了错误的信息并收到了凭据错误.

I know the username and pw data is being read correct by the server as I have tested with erroneous info and received credential error instead.

推荐答案

当您告诉cURL上传文件时,Content-Type标头会自动设置为multipart/form-data.对于像文档中这样的请求,您必须手动上传文件.

When you tell cURL to upload a file, the Content-Type header is automatically set to multipart/form-data. For a request like in your documentation, you would have to upload the file manually.

<?php
$url     = 'https://hostserver.com/gateway/remote_send';
$payload = array(
    'profile_name'  => 'username',
    'profile_pw'    => 'password1234',
    'attached_type' => 'action_1'
);
$file = realpath('/home/username/tests/test1234qwerty.csv');

// build multipart
$payload = http_build_query($payload);
$params  = "--ABC1234\r\n"
    . "Content-Type: application/x-www-form-urlencoded\r\n"
    . "\r\n"
    . $payload . "\r\n"
    . "--ABC1234\r\n"
    . "Content-Type: text/csv\r\n"
    . "Content-Disposition: attachment; filename=\"attachment.csv\"\r\n"
    . "\r\n"
    . file_get_contents($file) . "\r\n"
    . "--ABC1234--";

$first_newline      = strpos($params, "\r\n");
$multipart_boundary = substr($params, 2, $first_newline - 2);
$request_headers    = array();
$request_headers[]  = 'Content-Length: ' . strlen($params);
$request_headers[]  = 'Content-Type: multipart/x-api-remote-integration; boundary='
    . $multipart_boundary;

// send the request now

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);

$reply = curl_exec($ch);

行得通吗?

这篇关于带有文件附件的PHP Curl发布;自定义内容类型标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆