I am trying to upload a string (html) to my NextCloud over the Webdav API (documentation). I have used multipart file upload, because I read that it is the normal way to achieve file uploads to the API. When I upload a file it properly creates it and I the upload goes through, but it always adds this to the file:
----------------------------371289179749834008757921
Content-Disposition: form-data; name="data"
Hello world
----------------------------371289179749834008757921--
I just want the "Hello world" part to be put into the file. This is the code I use to upload the string as a file:
function sendToNextCloud(string $fileName, string $content)
{
$client = new Client();
$headers = [
'Authorization' => 'Basic Password',
];
$options = [
'multipart' => [
[
'name' => 'file',
'contents' => $content,
'filename' => $fileName,
'headers' => [
'Content-Type' => 'multipart/form-data'
]
]
]];
$request = new \GuzzleHttp\Psr7\Request('PUT', 'nextcloud:8080/remote.php/webdav/' . $fileName, $headers);
dump($request, $options);
$res = $client->sendAsync($request, $options)->wait();
dump($res->getBody()->getContents());
if ($res->getStatusCode() == 201) {
dump('Successfully sent');
}
return "test";
}
Do I need to alter the content type in the multipart headers, set a different option or use a different way of uploading?
Thank you for your help.
I found the solution to my problem:
use GuzzleHttp\Client;
$client = new Client();
$url = "https://webdav.example.com/file.txt";
$headers = [
'Content-Type' => 'text/plain',
'Authorization' => 'Basic ' . base64_encode('username:password')
];
$contents = "This is the contents of the file";
$response = $client->put($url, [
'headers' => $headers,
'body' => $contents
]);
if ($response->getStatusCode() == 201) {
echo "File uploaded successfully";
} else {
echo "Failed to upload file";
}
This creates a file from a simple string without using multipart and just a simple PUT method.
Related
I am trying to create Video ad Campaigns using LinkedIn API. I am using Laravel, Guzzle and I have followed steps given in documentation to upload video
Initialize Upload for Video
Upload the Video
Finalize Video Upload
On Initialization I receive success response with multiple upload Urls depending on the file size. Using these uploadUrl I am making request to upload the file chunk using Guzzle but in response it is throwing INternal server error 500. I understand it can be server error but not sure if that raised to any header, param or token.
Please help If anyone has faced similar issue and got resolved. I am sharing the response of the initialize upload and request being made using Guzzle.
Doc Link
Response of Initialize APi
{#1344 // app/Services/LinkedIn/LinkedInCampaignService.php:328
+"value": {#1324
+"uploadUrlsExpireAt": 1669664693370
+"video": "urn:li:video:C4D10AQGwksU16dn3Zw"
+"uploadInstructions": array:2 [
0 => {#1325
+"uploadUrl": "https://www.linkedin.com/dms-uploads/C4D10AQGwksU16dn3Zw/uploadedVideo?sau=aHR0cHM6Ly93d3cubGlua2VkaW4uY29tL2FtYnJ5L2FtYnJ5LXZpZGVvLz94LWxpLWFtYnJ5LWVwPUFRTE9OS2RwQmlCOS1BQUFBWVM2bndCNTd1MTR1Yjh5bVVKQ1BERDhFcVhIN1hxcXl1OHBiM3BuUVVCLV82dng2cjZscGVkWmNJajZFZXR2c2trZ1pKM1Z2MVJwWDRxQnQ4T1Z1SWxHNGlUbk85eF9tX082dE11MHhySnhod0RmbFNzUlBvWV90b1Fjdmd0TlZUTlNOQ2RlQkZKR2Zodk8tSktkcWlGMUFpa3pDZjVveDFMcnBQbkY3TXBaYkVkdlpKQXJnMGQ4R3gxQmFZWGR2SFA4aXdtRWRGdGlrSGNLRXVTa283eDhvWnNOZXRVX3I2WVlQa2dXaC1rZlVGbkh0MnNqVW03akItLVFtaGpzX3lwYTdiaEtMd0oxRFZyaEhvUE9KeGl2eFZKSEFELWVFM2txd2tHOWlvblByVm9IMU9tM2N4NXdTMU9TLUgtbjZyMmo4aHZIMFg5ckdlNWNSQkNjdUt0RmVCRkpGMzVoYnN1ZXdCZ3k1UkdxMjdpT1ZFVWRVVUdOelpxRWRKQXlGQXlFTTgteUtwbmVQalpORnFQcFVnVHl6cG80c3hqMGo2VDl6Nlp2cWNlcE1SaDBoZDRhY2Vhc1luUHNfUTc1cWNjbFBXQ2hKclpWU2NhaktRWk9WNlAyc3ZUU190cWFNQkZ1VGtWQ2Q3a0RIY2o5VmVaam1YY3hFREdpWVQzVmM4Vy1ieDdqZFRXMHBpRk9ZcURPTndTcjJZajNBZU4tcXVmRThtQy1qMzA4eEdic3NVQ0wxTTVSZTJjVmVxOS1pbDVQWmQ2MDRXU2lBSXhhejNDM09aenZmaXYtRkRwWlBIaEdscGVCYTdadFAycGRJMXR4eUpUdzVtcFFMTExiN1o2WGNscWoybWFlWkJwUkxZU0VIZXZ0Q29qMXNSUDRrcHQ0ZFluTUw1U0J6RV9qU2ZacW1pS21SS29RcnNrYWZrcUtUY0tMV1o5ZmZKTWZvaGNHTVE2ZTlRdlBJaGJHZ3ZSSFlWdFBjd1BOOG5uSG5rXzFIcE1SWWtWeGdoTVlhQm5KVGJrWDIxaExzYVBNVHlyM2FTQnlTME54c0c2UENMX202eDN2NlBmUC1nQXo1UDZOUGkxUHRubDE2Nm92Tm5ZNHNTdWxrNDdlaGVfZ1FZcnJDalZIbGVYZW4wU0g4TGUwaDNLczFLckdsekpyY0pqMjhQa29NQUdXN1ZCdktZN0ctdFZ0T0Q1cEswTTNsMUthUUQteGxsWnpVV3JLN2V2ZmtfZnEtZWNENTR5aHpKb1FVTzVmbWhDeDVIWERjT1ZYckhlWXlqVFlpbVQ5R1ZmdU9fbkdSZWtTczZENHZ6eVljejN1S0QxVmEzY3dnTU9heWQ4S3RBaVRjMGU3ZFVPdmJaMklNUnhnUlNKQnBaTmtDaHRybGRKQlJJUjRlakdMUkxJS2FpRElRUDlzMGkwUHZhNHVPOG8%253D&pn=1&m=91877349&app=4647153&sync=0&v=beta&ut=1cmOzfpLG0Caw1"
+"lastByte": 4194303
+"firstByte": 0
}
1 => {#1345
+"uploadUrl": "https://www.linkedin.com/dms-uploads/C4D10AQGwksU16dn3Zw/uploadedVideo?sau=aHR0cHM6Ly93d3cubGlua2VkaW4uY29tL2FtYnJ5L2FtYnJ5LXZpZGVvLz94LWxpLWFtYnJ5LWVwPUFRTE9OS2RwQmlCOS1BQUFBWVM2bndCNTd1MTR1Yjh5bVVKQ1BERDhFcVhIN1hxcXl1OHBiM3BuUVVCLV82dng2cjZscGVkWmNJajZFZXR2c2trZ1pKM1Z2MVJwWDRxQnQ4T1Z1SWxHNGlUbk85eF9tX082dE11MHhySnhod0RmbFNzUlBvWV90b1Fjdmd0TlZUTlNOQ2RlQkZKR2Zodk8tSktkcWlGMUFpa3pDZjVveDFMcnBQbkY3TXBaYkVkdlpKQXJnMGQ4R3gxQmFZWGR2SFA4aXdtRWRGdGlrSGNLRXVTa283eDhvWnNOZXRVX3I2WVlQa2dXaC1rZlVGbkh0MnNqVW03akItLVFtaGpzX3lwYTdiaEtMd0oxRFZyaEhvUE9KeGl2eFZKSEFELWVFM2txd2tHOWlvblByVm9IMU9tM2N4NXdTMU9TLUgtbjZyMmo4aHZIMFg5ckdlNWNSQkNjdUt0RmVCRkpGMzVoYnN1ZXdCZ3k1UkdxMjdpT1ZFVWRVVUdOelpxRWRKQXlGQXlFTTgteUtwbmVQalpORnFQcFVnVHl6cG80c3hqMGo2VDl6Nlp2cWNlcE1SaDBoZDRhY2Vhc1luUHNfUTc1cWNjbFBXQ2hKclpWU2NhaktRWk9WNlAyc3ZUU190cWFNQkZ1VGtWQ2Q3a0RIY2o5VmVaam1YY3hFREdpWVQzVmM4Vy1ieDdqZFRXMHBpRk9ZcURPTndTcjJZajNBZU4tcXVmRThtQy1qMzA4eEdic3NVQ0wxTTVSZTJjVmVxOS1pbDVQWmQ2MDRXU2lBSXhhejNDM09aenZmaXYtRkRwWlBIaEdscGVCYTdadFAycGRJMXR4eUpUdzVtcFFMTExiN1o2WGNscWoybWFlWkJwUkxZU0VIZXZ0Q29qMXNSUDRrcHQ0ZFluTUw1U0J6RV9qU2ZacW1pS21SS29RcnNrYWZrcUtUY0tMV1o5ZmZKTWZvaGNHTVE2ZTlRdlBJaGJHZ3ZSSFlWdFBjd1BOOG5uSG5rXzFIcE1SWWtWeGdoTVlhQm5KVGJrWDIxaExzYVBNVHlyM2FTQnlTME54c0c2UENMX202eDN2NlBmUC1nQXo1UDZOUGkxUHRubDE2Nm92Tm5ZNHNTdWxrNDdlaGVfZ1FZcnJDalZIbGVYZW4wU0g4TGUwaDNLczFLckdsekpyY0pqMjhQa29NQUdXN1ZCdktZN0ctdFZ0T0Q1cEswTTNsMUthUUQteGxsWnpVV3JLN2V2ZmtfZnEtZWNENTR5aHpKb1FVTzVmbWhDeDVIWERjT1ZYckhlWXlqVFlpbVQ5R1ZmdU9fbkdSZWtTczZENHZ6eVljejN1S0QxVmEzY3dnTU9heWQ4S3RBaVRjMGU3ZFVPdmJaMklNUnhnUlNKQnBaTmtDaHRybGRKQlJJUjRlakdMUkxJS2FpRElRUDlzMGkwUHZhNHVPOG8%253D&pn=2&m=91877349&app=4647153&sync=0&v=beta&ut=3GSFILXAS0Caw1"
+"lastByte": 5253879
+"firstByte": 4194304
}
]
+"uploadToken": ""
}
}
Calling Upload Urls
public function uploadChunkedVideo($fileName, $uploadInstructions)
{
try {
$fileHandler = fopen(storage_path('app') . '/' . $fileName, 'r');
$client = new Client();
$uploadPartIds = [];
foreach ($uploadInstructions as $instruction) {
$chunkedUpload = $client->put($instruction->uploadUrl, [
'headers' => [
'Content-Type' => 'application/octet-stream',
'Authorization' => 'Bearer ' . $this->accessToken,
'LinkedIn-Version' => config('services.linkedIn.version'),
],
'multipart' => [
[
'name' => $fileName,
'contents' => fread($fileHandler, $instruction->lastByte - $instruction->firstByte),
]
],
]);
//Push etag
$uploadPartIds[] = $chunkedUpload->getHeader('ETag')[0];
}
} catch (\GuzzleHttp\Exception\ServerException $e) {
dd($e->getResponse()->getBody()->getContents());
}
}
This worked for me.
$fileHandler = fopen(storage_path('app') . '/' . $fileName, 'r');
$client = new Client();
$uploadPartIds = [];
foreach ($uploadInstructions as $instruction) {
$chunkedUpload = $client->put($instruction->uploadUrl, [
'headers' => [
'Content-Type' => 'application/octet-stream',
'Authorization' => 'Bearer ' . $this->accessToken,
'LinkedIn-Version' => config('services.linkedIn.version'),
],
'body' => fread($fileHandler, $instruction->lastByte - $instruction->firstByte),
]);
//Push etag
$uploadPartIds[] = $chunkedUpload->getHeader('ETag')[0];
info($uploadPartIds);
}
return $uploadPartIds;
I'm using the Azure OCR Service to get the text of an image back (
https://learn.microsoft.com/de-de/azure/cognitive-services/Computer-vision/QuickStarts/PHP).
So far everything is up and running, but now I would like to use a local file instead of an already uploaded one.
$url->setQueryVariables($parameters);
$request->setMethod(HTTP_Request2::METHOD_POST);
// Request body
$request->setBody("{body}"); // Replace with the body, for example, "{"url": "http://www.example.com/images/image.jpg"}
Unfortunately I don't know how to pass the raw binary as the body of my POST request in PHP.
At first, when we refer local file, we should use 'Content-Type': 'application/octet-stream' in a header, then we can send requests that use a stream resource as the body.
Here's my working code using Guzzle for your reference:
<?php
require 'vendor/autoload.php';
$resource = fopen('./Shaki_waterfall.jpg', 'r');
$client = new \GuzzleHttp\Client();
$res = $client->request('POST', 'https://westus.api.cognitive.microsoft.com/vision/v1.0/analyze', [
'query' => [
'visualFeatures' => 'Categories',
'details' => '',
'language' => 'en'
],
'headers' => [
'Content-Type' => 'application/octet-stream',
'Ocp-Apim-Subscription-Key' => '<Ocp-Apim-Subscription-Key>'
],
'body' => $resource
]);
echo $res->getBody();
Using HTTP_Request2:
<?php
require_once 'HTTP/Request2.php';
$request = new Http_Request2('https://westus.api.cognitive.microsoft.com/vision/v1.0/analyze');
$url = $request->getUrl();
$headers = array(
'Content-Type' => 'application/octet-stream',
'Ocp-Apim-Subscription-Key' => '<Ocp-Apim-Subscription-Key>',
);
$request->setHeader($headers);
$parameters = array(
'visualFeatures' => 'Categories',
'details' => '',
'language' => 'en',
);
$url->setQueryVariables($parameters);
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setBody(fopen('./Shaki_waterfall.jpg', 'r'));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
I am able to upload a file to an API endpoint using Postman.
I am trying to translate that into uploading a file from a form, uploading it using Laravel and posting to the endpoint using Guzzle 6.
Screenshot of how it looks in Postman (I purposely left out the POST URL)
Below is the text it generates when you click the "Generate Code" link in POSTMAN:
POST /api/file-submissions HTTP/1.1
Host: strippedhostname.com
Authorization: Basic 340r9iu34ontoeioir
Cache-Control: no-cache
Postman-Token: 6e0c3123-c07c-ce54-8ba1-0a1a402b53f1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="FileContents"; filename=""
Content-Type:
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="FileInfo"
{ "name": "_aaaa.txt", "clientNumber": "102425", "type": "Writeoff" }
----WebKitFormBoundary7MA4YWxkTrZu0gW
Below is controller function for saving the file and other info. The file uploads correctly, I am able to get the file info.
I think the problem I am having is setting the multipart and headers array with the correct data.
public function fileUploadPost(Request $request)
{
$data_posted = $request->input();
$endpoint = "/file-submissions";
$response = array();
$file = $request->file('filename');
$name = time() . '_' . $file->getClientOriginalName();
$path = base_path() .'/public_html/documents/';
$resource = fopen($file,"r") or die("File upload Problems");
$file->move($path, $name);
// { "name": "test_upload.txt", "clientNumber": "102425", "type": "Writeoff" }
$fileinfo = array(
'name' => $name,
'clientNumber' => "102425",
'type' => 'Writeoff',
);
$client = new \GuzzleHttp\Client();
$res = $client->request('POST', $this->base_api . $endpoint, [
'auth' => [env('API_USERNAME'), env('API_PASSWORD')],
'multipart' => [
[
'name' => $name,
'FileContents' => fopen($path . $name, 'r'),
'contents' => fopen($path . $name, 'r'),
'FileInfo' => json_encode($fileinfo),
'headers' => [
'Content-Type' => 'text/plain',
'Content-Disposition' => 'form-data; name="FileContents"; filename="'. $name .'"',
],
// 'contents' => $resource,
]
],
]);
if($res->getStatusCode() != 200) exit("Something happened, could not retrieve data");
$response = json_decode($res->getBody());
var_dump($response);
exit();
}
The error I am receiving, screenshot of how it displays using Laravel's debugging view:
The way you are POSTing data is wrong, hence received data is malformed.
Guzzle docs:
The value of multipart is an array of associative arrays, each
containing the following key value pairs:
name: (string, required) the form field name
contents:(StreamInterface/resource/string, required) The data to use in the
form element.
headers: (array) Optional associative array of custom headers to use with the form element.
filename: (string) Optional
string to send as the filename in the part.
Using keys out of above list and setting unnecessary headers without separating each field into one array will result in making a bad request.
$res = $client->request('POST', $this->base_api . $endpoint, [
'auth' => [ env('API_USERNAME'), env('API_PASSWORD') ],
'multipart' => [
[
'name' => 'FileContents',
'contents' => file_get_contents($path . $name),
'filename' => $name
],
[
'name' => 'FileInfo',
'contents' => json_encode($fileinfo)
]
],
]);
$body = fopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);
http://docs.guzzlephp.org/en/latest/quickstart.html?highlight=file
In Laravel 8 with guzzle I am using this:
The idea is that you are reading the file with fread or file_get_content, then you can use the Laravel getPathname() which points to the file in /tmp
$response = $this
->apiClient
->setUserKey($userToken)
->post(
'/some/url/to/api',
[
'multipart' => [
'name' => 'avatar',
'contents' => file_get_contents($request->file('avatar')->getPathname()),
'filename' => 'avata.' . $request->file('avatar')->getClientOriginalExtension()
]
]
);
I'm sending an API request to Box.com to get the thumbnail of a PNG image. I'm using Laravel. When I'm using the following code I'm getting raw string data that I want to convert PNG image.
$client = new Client('https://api.box.com/{version}/files/{file_id}', [
'version' => '2.0',
'file_id' => $id,
'request.options' => [
'headers' => [
'Authorization' => 'Bearer ' . self::getAccessToken(),
]
]
]);
$request = $client->get('thumbnail.png?min_height=256&min_width=256');
try {
$response = $request->send();
dd($response->getBody(true));
Without returning the getBody() method string I don't get anything as Box.com will be returned with the contents of the thumbnail in the body.
Here's the example string I'm getting:
b"""
‰PNG\r\n
\x1A\n
\x00\x00\x00\rIHDR\x00\x00\x01\x00\x00\x00\x01\x00\x08\x06\x00\x00\x00\r¨f\x00\x00\x00\x06bKGD\x00ÿ\x00ÿ\x00ÿ ½§“\x00\x00\x00\tpHYs\x00\x00\x00H\x00\x00\x00H\x00FÉk>\x00\x00\x00\tvpAg\x00\x00\x01\x00\x00\x00\x01\x00\x00²gÜŠ\x00\x00€\x00IDATxÚÌýiŒ-[–߇ýö\x14Ã9™y3ï}ᄅޫªî®êê2%Ñ$[à \x19¶!Y&)\x1A”iC\x10`Ø0\x04I¶õÙ\x06,\x7F0\x0F$a›0!Û0M‘¢\x04\x0E¦Dv³\x075ÙÕC©ç¡º»z¨ù½\x1AÞ|ç\x1CΉˆ=ùÃÚ\x11'ÎÉ“Ã}]2\x1C\x0Fùnæ\x19"vìØkí5ü×\x7F©Óó'\x19#)…RŠ˜\x13™ù‘Ñãoy眧ïí;²|ˆë\x0FÅö\x05óôÿ4~B©qÌ?¹ýÕŒš>¿ÿÈ{Æ£”"ç<½7~\x7F¼¿Ý×wÏ“sFk½ýZÊ \x00\x12ÞwXcpÎñcÿäGøíßü5BPüþ—¾Ž±†\x14#\x19è;O×]\x00‰¾_ã½/3¤dš²"gEŒ\x11¥ÔtÍÍØ˳ș\x10#Zk¬5[ã\x1AŸWJ2»Z),š#ÆÇPÆž¶î{3G\t\r0*•ëRÖÆZGJi\x1A_y\x13\x15ÖT\fÞ“‰h5Η¡ª\x1CÚ\x18\x19óà‰1¢†\fYAUUÔuÍ0\f[ÏDk1\x1Ac\x1C9'B\x08TUÅb± gMí\x0Eù÷þÝÿ€ÿî\x7Fï_áÃ'ï¡ŒA;M&SåŒÒzöüT¹Ç²\UùㆵôÿoÇî3»êÏÈ<Úýg‚\x14eRµ ÕÖE\x00RJ{\x05cç4Üb8EP惓Co^$“IYm>ªæ\x0F-ï\x15ÎÛ>¼}“6\n
Õü~÷)»ËBRþVY\x16f\x1CÐ\x1A\x1E<xÈ_ùË\x7F™EÓÒwkÖë\x18#\x17\x17ç\x18c\x08>\x12Ä\x18I)\x10cœÎ•\x15¨œ\x01CJyKè'eE\x16¥“5Z+Œ¶“ ŒB©õ¶\n
•û1„\\x16~Ö#Þ{¯£°§,Š8\x15Á×J¡´"%EŒ‰œå»:Éx´QXeE¦væ\x162!\x04\x08ÊU4ÖÑ…\x04Q\x06\x14É\f\fhEÉ”9Ù܇(¥ñ\x08Á³^iÛ\x03ž>{Äßø›ÿ1_{ó+üÅÿÉÿ”>\U¶Š”\x1Dz6wj:›h€<{Äó¹Ø}Ö7¥›>£§g÷9n\x12þ}r2Wƒä”ÉãDŒS¢.\vÿøûø`æ\vr÷çºÁlÞß\x7Fù¡Pä4\x1A\x14£ÕPVnÙùwÏ?*©ÛŒgßw÷Ýëí\x1F#"\x13\x08¡çøø˜¿ÿ÷ÿ.¿÷{¿‹ÖŽÓ§kúÁ£µ,ê¾ï\x19\x06Oˆ‘˜â´ÐSJò\x13#1&RÊh}yÞ)S!ceë}™¢Ë\x16€R\n
cŒì¶Jì-äûƘÉJ˜Ïáø¤2²ãÇl\x08I\x11"(•€#Îò“ˆ$\x15‰9àCOïûÙcV[\x16L\x08\x01¥ÀY+c\x18Ç]þ‹1N?ãx¼÷Ó=Ž–R\x08‘~è9;\x7FJU+\x1E?y‡ÿìïü'üÌg\x7F†E]ã»\x0E•6s²µ.ÆŸG<^c¾á]wÌç÷ÆÏd™z]~H\x19•òô÷üGM?Yþ¥<¶2WE;_«M6ãß|È&5\x7F°y:±Ñ\n
ãì¥\t™Ÿì;e\x1EM¦×l‚.\v\x14h}…rØ£¡çç¹Í1í¶;nÍüïq\x11ì;¯ì\x142“!\x052"Ø'GGü½¿÷Ÿó³?û9¾÷{¿Ÿ\x0F\x1F< ÷žÞwX+\x06X\x08\x1E\fÞ\x0FÄ\x14\x10‹xŸÂºäô\žƒ¸3æÙï£ÐUUEJi\x12<Hh£ÐFîËÚ†¾ï'ÛwŒ»°Œ(ô\x13Ï,\x08-®KR\t2h¥‘Ó)òÌÚ\x00è‡\x01¯\x03É(bH"ú9#L$£Š|¦òyKJ‰aÐ8[Íž]$„HΉõúŒÃ£CŽ\x0F\x0Fù+\x7FåÿÈK¯üUþù\x7Fñ¿Åã'OX.Ýf:)›ËölnŸ«\¿ùßÛ›ã~Ï÷*ËtRæ)m¹&›‘̧2ð\x1D·y|?å<½µ»aoddöúÓ‹Çy\À(…¾”§›È»\x03Þ½»¼{C›kŒ\x0Fø*Óyòcaï.~ÝuPÛ\x13z\e\x05°ï3û\x1Eêh2ßÖ¯Úún\n
taÍÑbÉÃ\x07ïóïü;ÿK\x16Í]#\x11c “ñƒ‡œéûž¾\x1Fd×Lž\x10â4®4w\x03r"cQJO×\x11Aß\×\x1A‡RfÚ±Æç Ôæ>1Ôuµ–õz\rdb\x1CPJÏ”Ž™¬¹5tµ\v”PjÛ]J)cŒÞ|'\e(f<ˆ•1~?¥´eam”N\x002ιò¹éœÉ8SSW\vbô(•È$BJhmq®¢®\x174®Á\x0Fž”áoüÍ¿Å\v/Üålý”¦YÈwrBa‹BS›e¦Š\x1D|źÝ]só¿s¾z³š\x1Fzwy“E\x19Í]»\rgW!_z\x1ElÄä*¹Ø\x1AÃÎÝMÚcnY>\x00Ì\x17çü{»æøü³J)2Š´õ³çØØA“ðß4Žç\x19óüßçµnæ÷–RÂ\x02Ýê”ÿè/ý%â ‹»ëÖ¬V+Ö«5Cß³Z\x08!L®À\èÈ\x19=úØåÖ·\x03•\x1A¥2"$QLp\x15ÑF¡t&\x13G\eqúŽµ\x16k\r©ëŠ¶mpÎaŒ#¥LUÕhm&!ݧ,÷í†9³ež‹{¡ËwÆu´\x11à]·qsÂm×M\\x05MŒ©Ä\x17Ƶ‚\x04\x0EÕÜòbº×\x18Å\x12\x18úu·¢®\x1DëÕ\x05ÿç¿úWyvzŠVfR®JAVâjŒëJ+0*£È¨œP)A”ŸÑ\x1CÏyg=çòy\x10{b\fHÏ~¶ærßòÞ±<ækr\x1Eó¹ÊÍÈ;nëÍk¸Ä\x00òü\v{LÏ‹ßF\x1AJ`nôÓ®\vœMç\x1Fýݙ߹{ì¾~\eÿþºÏìúúû”ÓíŽmí\x1F\x06ÏñCþÊ_ù?ñæW¿ÆA}‡¾ëI)•\x1D¿g\x18\x06Bð\fÃÀ0øiל+J¥ÔF‚Ô¾lÉÆnR\n
RÊ[Šd¾«j‹°\eŒ1²àË÷mp¶Áššº^Hl`Çú\x19M~õôžµ¶ü¾]PJQUM±Fdg\x7Fn\ WLãìy¥K\x01ÉyÌ#çqGTEð7ë'F\t¤\x06ßs~q΋/ÞãÇ~ô\x1Fó\x0FÿÁ?äèè„uwQ\x02ŸvÚu·×Æ•ÃÛz\x06ã#Ú\x08½(\x10ÚñáE™èœÐÈç2iKñl6¶¼y>;\eÞMY·<›Ã›â\x169ƒV%\x12¨•BoìÅí%¶'ò\x7F8Ì\x16Ý8˜]µ+˜i.|W(šÍw/¿öQŽ}©¿yŠlþÞüõKãʱ<#Mß_prÒð\x13?úÃüê/\x7Fžû/½N7x\x06?L»d\x08Pv©\x10\x02>xB\f¨Ùœ¥Q9•hù|wÜÝiE\x10M\x11‚0\tÿ˜\x01\x18?\eBÀûHJ\n
"""
I got the success response for image as unique string values
$response = $this->client->request('GET', '/ap/generate-example/qr/image', [
'headers' => [
'Content-Type' => 'application/json',
'user_name' => 'user_name',
'password' => 'password',
'Authorization' => "Bearer assdadga",
'width' => '300',
'height' => '300',
'imgtype' => 'jpg'
],
// 'sink' => '/uploads/images'
]);
$body = $response->getBody();
$base64 = base64_encode($body);
$mime = "image/jpeg";
$img = ('data:' . $mime . ';base64,' . $base64);
dd($img);
Output:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCADcANwBAREA/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaE
let's view this with
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQA" />
I've figured it out myself using Guzzle3 on Laravel 5.1. Here's the relevant code which I hope you may find helpful in future:
In your model or if you prefer to use controller then it's fine:
/**
* Get download link from Box.com
*
* #param $id
* #return bool|int|string
*/
public static function getDownloadLink($id)
{
$client = new Client('https://api.box.com/{version}/files/{file_id}', [
'version' => '2.0',
'file_id' => $id,
'request.options' => [
'headers' => [
'Authorization' => 'Bearer ' . self::getAccessToken(),
]
]
]);
$request = $client->get('content');
try {
$response = $request->send();
$result = $response->getEffectiveUrl();
} catch (BadResponseException $e) {
$result = $e->getResponse()->getStatusCode();
if ($result === 401) {
self::regenerateAccessToken();
return self::getDownloadLink($id);
}
}
return count($result) ? $result : false;
}
In the above static method, I've sent a GET request to the Box.com API and the API returns with an effectiveUrl and that's the direct download file link we're looking for.
Does anybody know the correct way to post JSON using Guzzle?
$request = $this->client->post(self::URL_REGISTER,array(
'content-type' => 'application/json'
),array(json_encode($_POST)));
I get an internal server error response from the server. It works using Chrome Postman.
For Guzzle 5, 6 and 7 you do it like this:
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post('url', [
GuzzleHttp\RequestOptions::JSON => ['foo' => 'bar'] // or 'json' => [...]
]);
Docs
The simple and basic way (guzzle6):
$client = new Client([
'headers' => [ 'Content-Type' => 'application/json' ]
]);
$response = $client->post('http://api.com/CheckItOutNow',
['body' => json_encode(
[
'hello' => 'World'
]
)]
);
To get the response status code and the content of the body I did this:
echo '<pre>' . var_export($response->getStatusCode(), true) . '</pre>';
echo '<pre>' . var_export($response->getBody()->getContents(), true) . '</pre>';
For Guzzle <= 4:
It's a raw post request so putting the JSON in the body solved the problem
$request = $this->client->post(
$url,
[
'content-type' => 'application/json'
],
);
$request->setBody($data); #set body!
$response = $request->send();
This worked for me (using Guzzle 6)
$client = new Client();
$result = $client->post('http://api.example.com', [
'json' => [
'value_1' => 'number1',
'Value_group' =>
array("value_2" => "number2",
"value_3" => "number3")
]
]);
echo($result->getBody()->getContents());
$client = new \GuzzleHttp\Client();
$body['grant_type'] = "client_credentials";
$body['client_id'] = $this->client_id;
$body['client_secret'] = $this->client_secret;
$res = $client->post($url, [ 'body' => json_encode($body) ]);
$code = $res->getStatusCode();
$result = $res->json();
You can either using hardcoded json attribute as key, or you can conveniently using GuzzleHttp\RequestOptions::JSON constant.
Here is the example of using hardcoded json string.
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post('url', [
'json' => ['foo' => 'bar']
]);
See Docs.
$client = new \GuzzleHttp\Client(['base_uri' => 'http://example.com/api']);
$response = $client->post('/save', [
'json' => [
'name' => 'John Doe'
]
]);
return $response->getBody();
This works for me with Guzzle 6.2 :
$gClient = new \GuzzleHttp\Client(['base_uri' => 'www.foo.bar']);
$res = $gClient->post('ws/endpoint',
array(
'headers'=>array('Content-Type'=>'application/json'),
'json'=>array('someData'=>'xxxxx','moreData'=>'zzzzzzz')
)
);
According to the documentation guzzle do the json_encode
Solution for $client->request('POST',...
For those who are using $client->request this is how you create a JSON request:
$client = new Client();
$res = $client->request('POST', "https://some-url.com/api", [
'json' => [
'paramaterName' => "parameterValue",
'paramaterName2' => "parameterValue2",
]
'headers' => [
'Content-Type' => 'application/json',
]
]);
Guzzle JSON Request Reference
Php Version: 5.6
Symfony version: 2.3
Guzzle: 5.0
I had an experience recently about sending json with Guzzle. I use Symfony 2.3 so my guzzle version can be a little older.
I will also show how to use debug mode and you can see the request before sending it,
When i made the request as shown below got the successfull response;
use GuzzleHttp\Client;
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
"Content-Type" => "application/json"
];
$body = json_encode($requestBody);
$client = new Client();
$client->setDefaultOption('headers', $headers);
$client->setDefaultOption('verify', false);
$client->setDefaultOption('debug', true);
$response = $client->post($endPoint, array('body'=> $body));
dump($response->getBody()->getContents());
#user3379466 is correct, but here I rewrite in full:
-package that you need:
"require": {
"php" : ">=5.3.9",
"guzzlehttp/guzzle": "^3.8"
},
-php code (Digest is a type so pick different type if you need to, i have to include api server for authentication in this paragraph, some does not need to authenticate. If you use json you will need to replace any text 'xml' with 'json' and the data below should be a json string too):
$client = new Client('https://api.yourbaseapiserver.com/incidents.xml', array('version' => 'v1.3', 'request.options' => array('headers' => array('Accept' => 'application/vnd.yourbaseapiserver.v1.1+xml', 'Content-Type' => 'text/xml'), 'auth' => array('username#gmail.com', 'password', 'Digest'),)));
$url = "https://api.yourbaseapiserver.com/incidents.xml";
$data = '<incident>
<name>Incident Title2a</name>
<priority>Medium</priority>
<requester><email>dsss#mail.ca</email></requester>
<description>description2a</description>
</incident>';
$request = $client->post($url, array('content-type' => 'application/xml',));
$request->setBody($data); #set body! this is body of request object and not a body field in the header section so don't be confused.
$response = $request->send(); #you must do send() method!
echo $response->getBody(); #you should see the response body from the server on success
die;
--- Solution for * Guzzle 6 * ---
-package that you need:
"require": {
"php" : ">=5.5.0",
"guzzlehttp/guzzle": "~6.0"
},
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://api.compay.com/',
// You can set any number of default request options.
'timeout' => 3.0,
'auth' => array('you#gmail.ca', 'dsfddfdfpassword', 'Digest'),
'headers' => array('Accept' => 'application/vnd.comay.v1.1+xml',
'Content-Type' => 'text/xml'),
]);
$url = "https://api.compay.com/cases.xml";
$data string variable is defined same as above.
// Provide the body as a string.
$r = $client->request('POST', $url, [
'body' => $data
]);
echo $r->getBody();
die;
Simply use this it will work
$auth = base64_encode('user:'.config('mailchimp.api_key'));
//API URL
$urll = "https://".config('mailchimp.data_center').".api.mailchimp.com/3.0/batches";
//API authentication Header
$headers = array(
'Accept' => 'application/json',
'Authorization' => 'Basic '.$auth
);
$client = new Client();
$req_Memeber = new Request('POST', $urll, $headers, $userlist);
// promise
$promise = $client->sendAsync($req_Memeber)->then(function ($res){
echo "Synched";
});
$promise->wait();
I use the following code that works very reliably.
The JSON data is passed in the parameter $request, and the specific request type passed in the variable $searchType.
The code includes a trap to detect and report an unsuccessful or invalid call which will then return false.
If the call is sucessful then json_decode ($result->getBody(), $return=true) returns an array of the results.
public function callAPI($request, $searchType) {
$guzzleClient = new GuzzleHttp\Client(["base_uri" => "https://example.com"]);
try {
$result = $guzzleClient->post( $searchType, ["json" => $request]);
} catch (Exception $e) {
$error = $e->getMessage();
$error .= '<pre>'.print_r($request, $return=true).'</pre>';
$error .= 'No returnable data';
Event::logError(__LINE__, __FILE__, $error);
return false;
}
return json_decode($result->getBody(), $return=true);
}
The answer from #user3379466 can be made to work by setting $data as follows:
$data = "{'some_key' : 'some_value'}";
What our project needed was to insert a variable into an array inside the json string, which I did as follows (in case this helps anyone):
$data = "{\"collection\" : [$existing_variable]}";
So with $existing_variable being, say, 90210, you get:
echo $data;
//{"collection" : [90210]}
Also worth noting is that you might want to also set the 'Accept' => 'application/json' as well in case the endpoint you're hitting cares about that kind of thing.
Above answers did not worked for me somehow. But this works fine for me.
$client = new Client('' . $appUrl['scheme'] . '://' . $appUrl['host'] . '' . $appUrl['path']);
$request = $client->post($base_url, array('content-type' => 'application/json'), json_encode($appUrl['query']));