CURL: sending images using border in REST API

I am currently working with some kind of API. I wrote simple functions that allow me to add new content, however Im getting stuck when loading images.

Here's a simple CURL command in the documentation:

curl -v -s -u username:password \
  -H "Content-Type: multipart/form-data" \
  -H "Accept: application/api+json" \
  -F "image=@img1.jpeg;type=image/jpeg" \
  -F "image=@img2.jpeg;type=image/jpeg" \
  -XPUT ''

      

And sample REQUEST:

PUT /images HTTP/1.1
Host: example
Content-Type: multipart/form-data; boundary=vjrLeiXjJaWiU0JzZkUPO1rMcE2HQ-n7XsSx

--vjrLeiXjJaWiU0JzZkUPO1rMcE2HQ-n7XsSx
Content-Disposition: form-data; name="image"; filename="img1.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: binary

      

Now there is my function:

$headers_put = array( 
   "Content-Type: multipart/form-data; boundary=vjrLeiXjJaWiU0JzZkUPO1rMcE2HQ-n7XsSx",
   "Accept: application/+json",  
); 

function putImages($ch, $headers, $ad, $images){
    $url = '/images';

    $files = [];

    foreach($images as $key => $image) {
        $number = $key +1;
        $paths = parse_url($image, PHP_URL_PATH);
        $paths = $_SERVER['DOCUMENT_ROOT'] . $paths;

        $cfile = new CURLFile(''. $paths, 'image/jpeg', 'image'.$key);
        $files[$key] = $cfile;

    }

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $files);

    $result = curl_exec($ch);
    var_dump($result);

    echo curl_getinfo($ch, CURLINFO_HTTP_CODE);
    echo "\n";

}

      

Finally, the answer is:

{"errors":{"error":{"@key":"unsupported-form-element"}}}"

      

What am I doing wrong? Any ideas? Thank you for any help.

+3


source to share


2 answers


After several approaches using curl_file_create without making it work. I think the mobile.de-API is just poorly implemented.

As a result, I created a custom routine for CURLOPT_POSTFIELDS that manually creates the complete set. I borrowed most of the code from the PHP man page as "the CURLFile class".



  • Create an array of filenames
  • Create a multi-page header (see code below)

    function curl_custom_postfields(array $files = array())    {
    
    // build file parameters
    foreach ($files as $k => $v) {
        switch (true) {
            case false === $v = realpath(filter_var($v)):
            case !is_file($v):
            case !is_readable($v):
                continue; // or return false, throw new InvalidArgumentException
        }
        $data = file_get_contents($v);
        $body[] = implode("\r\n", array(
            "Content-Disposition: form-data; name=\"image\"",
            "Content-Type: image/jpeg",
            "",
            $data,
        ));
    }
    
    // generate safe boundary
    do {
        $boundary = "---------------------" . md5(mt_rand() . microtime());
    } while (preg_grep("/{$boundary}/", $body));
    
    // add boundary for each parameters
    array_walk($body, function (&$part) use ($boundary) {
        $part = "--{$boundary}\r\n{$part}";
    });
    
    // add final boundary
    $body[] = "--{$boundary}--";
    $body[] = "";
    
    // set options
    return array(implode("\r\n", $body), $boundary);    
    }
    
          

  • Use this feature;)

    $postfields = $this->curl_custom_postfields($files);
    
          

  • Add border to http header

    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data; boundary=' . $postfields[1], 'Accept: application/vnd.de.mobile.api+json'));
    
          

  • Add Postfields

    curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields[0]);
    
          

This is not the cleanest solution, so please use it with care. But at least it works.

+2


source


I have the same problem and found a solution but only for single images. The trick is that your array should look like this:

$images = array(
  'image' => 'PATH/IMG.jpg',
);

      



This means that the key must be "image" and nothing else! I hope this helps;)

0


source







All Articles