Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
PHP upload file with curl (multipart/form-data)

We want to upload file to a server with POST HTTP request. We will use curl functions.


// data fields for POST request
$fields = array("f1"=>"value1", "another_field2"=>"anothervalue");

// files to upload
$filenames = array("/tmp/1.jpg", "/tmp/2.png");

$files = array();
foreach ($filenames as $f){
   $files[$f] = file_get_contents($f);
}

// URL to upload to
$url = "http://site.com/upload";


// curl

$curl = curl_init();

$url_data = http_build_query($data);

$boundary = uniqid();
$delimiter = '-------------' . $boundary;

$post_data = build_data_files($boundary, $fields, $files);


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 => $post_data,
  CURLOPT_HTTPHEADER => array(
    //"Authorization: Bearer $TOKEN",
    "Content-Type: multipart/form-data; boundary=" . $delimiter,
    "Content-Length: " . strlen($post_data)

  ),

  
));


//
$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);




function build_data_files($boundary, $fields, $files){
    $data = '';
    $eol = "\r\n";

    $delimiter = '-------------' . $boundary;

    foreach ($fields as $name => $content) {
        $data .= "--" . $delimiter . $eol
            . 'Content-Disposition: form-data; name="' . $name . "\"".$eol.$eol
            . $content . $eol;
    }


    foreach ($files as $name => $content) {
        $data .= "--" . $delimiter . $eol
            . 'Content-Disposition: form-data; name="' . $name . '"; filename="' . $name . '"' . $eol
            //. 'Content-Type: image/png'.$eol
            . 'Content-Transfer-Encoding: binary'.$eol
            ;

        $data .= $eol;
        $data .= $content . $eol;
    }
    $data .= "--" . $delimiter . "--".$eol;


    return $data;
}


see examples:
https://gist.github.com/iansltx/a6ed41d19852adf2e496
@jaschaio
Copy link

jaschaio commented Nov 26, 2017

I love you. Tried a lot, this finally worked like I needed it.

@chmureck
Copy link

chmureck commented Dec 16, 2017

Thanks for that, was very useful.
There is a small typo near the beginning:
$url_data = http_build_query($data);
should be
$url_data = http_build_query($fields);

@SoLoGHoST
Copy link

SoLoGHoST commented Jan 4, 2018

Where is $url_data even used at? It seems that you have variables being generated that aren't even used.

@aliosmanyuksel
Copy link

aliosmanyuksel commented Jan 7, 2018

$filenames = array("/tmp/1.jpg", "/tmp/2.png");; ---> false
$filenames = array("/tmp/1.jpg", "/tmp/2.png"); ----> true

@GennadiyBilyk
Copy link

GennadiyBilyk commented Mar 12, 2018

Thanks a lot

@inspiration-tech
Copy link

inspiration-tech commented Jul 5, 2018

It works! Thank you, man

@systemerrorhy
Copy link

systemerrorhy commented Aug 2, 2018

can someone explain to me the line: $ fields = array ("f1" => "value1", "another_field2" => "anothervalue");
Is it mandatory to have or different web?

@systemerrorhy
Copy link

systemerrorhy commented Aug 2, 2018

good

@gangareddy-interakt
Copy link

gangareddy-interakt commented Aug 28, 2018

Thanks

@rodesmola
Copy link

rodesmola commented Sep 18, 2018

Nice one, thank you!!

@robtimus
Copy link

robtimus commented Oct 31, 2018

I found this when searching for a streaming multipart/form-data solution for cURL. Because I couldn't find any I wrote my own: https://packagist.org/packages/robtimus/multipart. This works like the above code but doesn't put everything in memory; it uses cURLs read function instead.

@faai5200
Copy link

faai5200 commented Nov 14, 2018

$filenames = array("/tmp/1.jpg", "/tmp/2.png");; ---> false
$filenames = array("/tmp/1.jpg", "/tmp/2.png"); ----> true

Not an issue bro :)

@jef531
Copy link

jef531 commented Apr 6, 2020

Very nice! Thanks,

@dilshad112
Copy link

dilshad112 commented Apr 12, 2020

Its work . awesome

@harrisonhenri
Copy link

harrisonhenri commented May 29, 2020

Very nice! You save my life!

@shawnchong
Copy link

shawnchong commented Jul 26, 2020

Holy crap, it WORKS and is easily customizable, thanks man.

@ElyVega
Copy link

ElyVega commented Oct 21, 2020

Thanks a lot! Works like a charm

@defalt4
Copy link

defalt4 commented Feb 9, 2021

Thanks, it helps me alot!

@RatanaKH
Copy link

RatanaKH commented May 28, 2021

Nice, It works very well!

@tiagoa
Copy link

tiagoa commented Sep 28, 2021

Thanks a lot!

@jez321
Copy link

jez321 commented Feb 12, 2022

Probably a silly question but what's the reason we need to build the multipart data manually, is it not possible to have curl handle it e.g. https://stackoverflow.com/a/11825645

@luowencai
Copy link

luowencai commented Aug 2, 2022

Thanks a lot!

@MandelaMan
Copy link

MandelaMan commented Aug 4, 2022

Bless you whoever you are!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment