4

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 ().

2 Answers 2

10

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

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.