40

I am trying to post an image with cURL in PHP using multipart/form-data header since API that I am sending to is expecting image to be sent as multi-part form.

I don't have problems talking to the API with other requests; only posting an image is an issue.

I am using this form on client side:

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

and this is the server I am posting to (here I am trying to post this data forward to an 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;

With the code below I am able to see my request headers:

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

var_dump(curl_getinfo($ch));

The content-type in request-headers is shown correctly now. But it seems the image is not send correctly as API would expect. Unfortunately I don't have access to the API...

Any help appreciated, thank you

3
  • 1
    check this url: php-guru.in/2013/upload-files-using-php-curl Commented Feb 20, 2014 at 11:33
  • This worked after some minor modifications regarding my structure etc. You can post as an answer if you want... Commented Feb 20, 2014 at 12:03
  • its ok, if it worked for you :) Commented Feb 20, 2014 at 12:19

3 Answers 3

77

As of PHP 5.6 @$filePath will not work in CURLOPT_POSTFIELDS without CURLOPT_SAFE_UPLOAD being set and it is completely removed in PHP 7. You will need to use a CurlFile object, RFC here.

$fields = [
    'name' => new \CurlFile($filePath, 'image/png', 'filename.png')
];
curl_setopt($resource, CURLOPT_POSTFIELDS, $fields);
Sign up to request clarification or add additional context in comments.

1 Comment

This was really useful for me, guiding me not to use @ in my project any more, and use CurlFile instead. Thank you!
27

In case anyone had the same problem: check this as @PravinS suggested. I used the exact same code as shown there and it worked for me perfectly.

This is the relevant part of the server code that helped:

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 should look something like:

<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>

3 Comments

So what part of the code solved the problem you were having? Posting the relevant code snippet will help others that run into the same problem. (Especially if that link breaks or changes)
Why are people not using the CURLFile function? I am trying to but it's not working, nor am I finding working code snippets with it's use. Did you ignore CURLFile class altogether on purpose?
@Erik the CURLFile class is available for >= PHP 5.5. As (among other systems) the current debian stable (wheezy at this time) use PHP 5.4 out of the box, they cant use the CURLFile class.
0

CURL OPERATION BETWEEN SERVER TO SERVER WITHOUT HTML FORM IN PHP USING MULTIPART/FORM-DATA

// files to upload

$filename = "https://example.s3.amazonaws.com/0.jpg";       

// URL to upload to (Destination server)

$url = "https://otherserver/image";

AND

    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        //CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => "POST",
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => file_get_contents($filename),
        CURLOPT_HTTPHEADER => array(
            //"Authorization: Bearer $TOKEN",
            "Content-Type: multipart/form-data",
            "Content-Length: " . strlen(file_get_contents($filename)),
            "API-Key: abcdefghi" //Optional if required
        ),
    ));

   $response = curl_exec($curl);

    $info = curl_getinfo($curl);
//echo "code: ${info['http_code']}";

//print_r($info['request_header']);

    var_dump($response);
    $err = curl_error($curl);

    echo "error";
    var_dump($err);
    curl_close($curl);

1 Comment

almost working.. I get Missing boundary in multipart/form-data POST data in <b>Unknown</b> on line <b>0</b>

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.