web-dev-qa-db-ja.com

curlで生の画像データをmultipart / form-dataとして投稿する

私が送信しているAPIは、画像がマルチパートフォームとして送信されることを期待しているため、multipart/form-dataヘッダーを使用して、PHP=.

他のリクエストでAPIと通信するのに問題はありません。画像の投稿のみが問題です。

私はクライアント側でこのフォームを使用しています:

<form action="http://myServerURL" method="POST" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="Submit">
</form>

これは、私が投稿しているサーバーです(ここでは、このデータをAPIに転送しようとしています)。

$ch = curl_init($url);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $imgRawData); // <-- raw data here hm?
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($ch, CURLOPT_COOKIEFILE, $cookieJar);
curl_setopt( $ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, 1); <-- using this as I wanted to check if HTTPHEADER is set
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data')); <-- setting content-type header?
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);

// i get response from the server
$response = curl_exec( $ch );

// with this I can check what kind of content type the last request had?
$requestContentType = curl_getinfo($ch,CURLINFO_CONTENT_TYPE);
echo "<br>request Content Type was:".$requestContentType."<br>";    

curl_close($ch);

echo "<br><b>SERVER POST IMAGE RESPONSE:</b><br>";
echo $response;

以下のコードを使用すると、リクエストヘッダーを確認できます。

curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);

var_dump(curl_getinfo($ch));

リクエストヘッダーのコンテンツタイプが正しく表示されるようになりました。しかし、APIが期待するように、画像は正しく送信されないようです。残念ながら、APIにアクセスできません...

助けてくれてありがとう、ありがとう

24
trainoasis

誰かが同じ問題を抱えていた場合:@ -PravinSが示唆したように this をチェックしてください。そこに示されているものとまったく同じコードを使用しましたが、完全に機能しました。

これは、助けとなったサーバーコードの関連部分です。

if (isset($_POST['btnUpload']))
{
$url = "URL_PATH of upload.php"; // e.g. http://localhost/myuploader/upload.php // request URL
$filename = $_FILES['file']['name'];
$filedata = $_FILES['file']['tmp_name'];
$filesize = $_FILES['file']['size'];
if ($filedata != '')
{
    $headers = array("Content-Type:multipart/form-data"); // cURL headers for file uploading
    $postfields = array("filedata" => "@$filedata", "filename" => $filename);
    $ch = curl_init();
    $options = array(
        CURLOPT_URL => $url,
        CURLOPT_HEADER => true,
        CURLOPT_POST => 1,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_POSTFIELDS => $postfields,
        CURLOPT_INFILESIZE => $filesize,
        CURLOPT_RETURNTRANSFER => true
    ); // cURL options
    curl_setopt_array($ch, $options);
    curl_exec($ch);
    if(!curl_errno($ch))
    {
        $info = curl_getinfo($ch);
        if ($info['http_code'] == 200)
            $errmsg = "File uploaded successfully";
    }
    else
    {
        $errmsg = curl_error($ch);
    }
    curl_close($ch);
}
else
{
    $errmsg = "Please select the file";
}
}

htmlフォームは次のようになります。

<form action="uploadpost.php" method="post" name="frmUpload" enctype="multipart/form-data">
<tr>
  <td>Upload</td>
  <td align="center">:</td>
  <td><input name="file" type="file" id="file"/></td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td align="center">&nbsp;</td>
  <td><input name="btnUpload" type="submit" value="Upload" /></td>
</tr>
21
trainoasis

PHP 5.6の時点で@$filePathCURLOPT_POSTFIELDSで機能しません。CURLOPT_SAFE_UPLOADが設定されていないとPHP 7.で完全に削除されます。 CurlFile オブジェクトを使用するには、 RFC here

$fields = [
    'name' => new \CurlFile($filePath, 'image/png', 'filename.png')
];
curl_setopt($resource, CURLOPT_POSTFIELDS, $fields);
43
b3n