Im currently working with some kind of API. I have wrote simple functions which allows me to add new content, however Im stuck on uploading images.
Here's simple CURL command in documentation:
curl -v -s -u username:password \
-H "Content-Type: multipart/form-data" \
-H "Accept: application/api+json" \
-F "[email protected];type=image/jpeg" \
-F "[email protected];type=image/jpeg" \
-XPUT ''
And a 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 response is:
{"errors":{"error":{"@key":"unsupported-form-element"}}}"
What Im doing wrong? Any ideas? Thank you kindly for any help.
After several approaches using curl_file_create without getting it to work. I think the mobile.de-API is just implemented badly.
I ended up implementing a custom routine for CURLOPT_POSTFIELDS that is creating the complete multipart manually. I borrowed most of the code from the PHP manpage as "The CURLFile class".
Create multipart 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 that function ;)
$postfields = $this->curl_custom_postfields($files);
Add boundary 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]);
It's not the cleanest solution at all so please use it with care. But at least it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With