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.
source to share
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.
source to share