Skip to content

Instantly share code, notes, and snippets.

@maxivak
Last active April 4, 2024 10:07
Show Gist options
  • Save maxivak/18fcac476a2f4ea02e5f80b303811d5f to your computer and use it in GitHub Desktop.
Save maxivak/18fcac476a2f4ea02e5f80b303811d5f to your computer and use it in GitHub Desktop.
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
@Hmerman6006
Copy link

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

@jez321 you are correct. Thanks for sharing. Struggled for hours before reading your comment and following the link. After a few additional tests I noticed the curl api adds the headers for you, but only if your CURLOPT_POSTFIELDS is a single dimensional array and that you have no raw byte fields in the post packet.

@Roboxkin
Copy link

It didn't work for me, I went through a lot of options.
I tried to send a picture, but without success. Probably the code is no longer working.

@ipehimanshu
Copy link

Hello

if data has multi dimensional then it not working,

does anyone has solution ?

Thank you

@Xelone28
Copy link

Xelone28 commented Feb 5, 2024

Works great thanks !

@oulina
Copy link

oulina commented Feb 10, 2024

Thank you very much!!!

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