Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send file using multipart/form-data request in php

I have image resource stored in variable which I need to send to server using its http API and PHP. I have to send request with content type multipart/form-data. So, I need to make similiar request as when form with file input and enctype=multipart/form-data attribute is sent. I tried this:

<?php
$url = 'here_is_url_for_web_API';
$input = fopen('delfin.jpg','r');       
$header = array('Content-Type: multipart/form-data');
$resource = curl_init();
curl_setopt($resource, CURLOPT_URL, $url);
curl_setopt($resource, CURLOPT_USERPWD, "user:password");
curl_setopt($resource, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
curl_setopt($resource, CURLOPT_HTTPHEADER, $header);
curl_setopt($resource, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($resource, CURLOPT_BINARYTRANSFER, true );
curl_setopt($resource, CURLOPT_INFILESIZE, 61631);
curl_setopt($resource, CURLOPT_INFILE, $input);
$result = curl_exec($resource);
curl_close($resource);
var_dump($result);
?>

I don't know how exactly response should look like but this returns: http status 405 and error report is: The specified HTTP method is not allowed for the requested resource ().

like image 696
1daemon1 Avatar asked Feb 15 '23 19:02

1daemon1


2 Answers

use multipart/form-data and boundaries in POST content with curl.

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

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

// more fields for POST request
$fields = array("f1"=>"value1", "another_field2"=>"anothervalue");
    
$url = "http://example.com/upload";

$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 the full example here: https://gist.github.com/maxivak/18fcac476a2f4ea02e5f80b303811d5f

like image 52
Max Ivak Avatar answered Feb 18 '23 08:02

Max Ivak


If you work with CURL, you have to just:

1, set header 'Content-Type' as 'multipart/form-data;'

2, set option 'RETURNTRANSFER' of curl to true (use option method of curl)

3, set option 'POST' of curl to true (use option method of curl)

4, get source of your file (what you get from fopen in PHP):

$tempFile = tempnam(sys_get_temp_dir(), 'File_');                
file_put_contents($tempFile, $source);
$post = array(
    "uploadedFile" => "@" . $tempFile, //"@".$tempFile.";type=image/jpeg",
);

5, use post method of CURL with parameter in $post variable

like image 30
1daemon1 Avatar answered Feb 18 '23 08:02

1daemon1