I am using Guzzle 6 and I can't pass array with form_params in the body of the client
$postFields = [
form_params => [
'data[test]' => "TEST",
'data[whatever]' => "Whatever..."
]
];
$client = new GuzzleClient([
'cookies' => $jar, // The cookie
'allow_redirects' => true, // Max 5 Redirects
'base_uri' => $this->navigateUrl, // Base Uri
'headers' => $this->headers
]);
$response = $client->post('api',[$postFields]);
Finally, when i send the request my data is gone... But if I manually add the the data in the response it's working fine.
$response = $client->post(
'api',
[form_params => [
'data[test]'=>"TEST",
'data[wht]' => 'Whatever'
],
]
// It's working this way...
I hope I am clear enough if u need more info feel free to ask. Thanks in advance.
I see a couple of issues. First is the fact that your $postFields array does not appear to be properly formatted, and second you wrap your $postFields array inside another array.
$options = [
'debug' => true,
'form_params' => [
'test' => 15,
'id' => 43252435243654352,
'name' => 'this is a random name',
],
'on_stats' => $someCallableItem,
];
$response = $client->post('api', $options);
Related
Question: How to update the price of a woocommerce product via API using Guzzle and guzzle/oauth-subscriber
I've used This Question as my reference to get oauth1 working for requesting data, which works well. Just haven't been able to workout out to send post variables.
Most tutorials and the guzzle docs use the $client->request('GET', 'http://httpbin.org', [ 'query' => ['foo' => 'bar'] ]); but that isn't working either:
$response = $client->request('POST', $endpoint, [
'auth' => 'oauth',
'form_params' => [
'price' => '21'
]
]);
This is my current code, with the get $client->get() commented out what successfully returns a product.
$endpoint = 'products/12';
$handler = new \GuzzleHttp\Handler\CurlHandler();
$stack = \GuzzleHttp\HandlerStack::create($handler);
$middleware = new \GuzzleHttp\Subscriber\Oauth\Oauth1([
'consumer_key' => $this->consumer_key,
'consumer_secret' => $this->consumer_secret,
'token_secret' => '',
'token' => '',
'request_method' => Oauth1::REQUEST_METHOD_QUERY,
'signature_method' => Oauth1::SIGNATURE_METHOD_HMAC
]);
$stack->push($middleware);
$client = new \GuzzleHttp\Client([
'base_uri' => $this->url . $this->api,
'handler' => $stack
]);
$response = $client->post( $endpoint, [ 'auth' => 'oauth' ], ['price' => '21'] );
var_dump($response);
//$response = $client->get( $endpoint, [ 'auth' => 'oauth' ] );
//return array(
// 'status' => $response->getStatusCode(),
// 'header' => $response->getHeaderLine('content-type'),
// 'body' => json_decode($response->getBody())
//);
There were three issues with my code:
Using POST to update, not PUT. As stated POST is to create, not update.
Reading Woocommerce docs I found that 'price' is read only, so no combination of parameters I was trying were going to work. regular_price is the correct parameter to use here.
None of the options I was passing to $client-> were working, it needs to be a query string. Which I appended to the $endpoint variable.
$endpoint .= "?stock_quantity=456";
$response = $client->put( $endpoint, [ 'auth' => 'oauth' ] );
I am having a hard time converting cURL to Guzzle6. I'm want to send a name and reference UUID via JSON AND the contents of an XML file to process to a REST endpoint.
cURL
curl -H 'Expect:' -F
'request={"name":"test", "reference":"870e0320-021e-4c67-9169-d4b2c7e5b9c9"}'
-F 'file=#sample.xml' http://ec2-48-88-173-9.us-east-1.compute.amazonaws.com:8180/rs/process
Guzzle
$client = new Client(['debug' => true]);
$request = $client->request('POST',
'http://ec2-48-88-173-9.us-east-1.compute.amazonaws.com:8180/rs/process', [
'multipart' => [
[
'name' => 'data',
'contents' => "{'name':'test','reference':870e0320-021e-4c67-9169-d4b2c7e5b9c9}",
'headers' => ['Content-Type' => 'application/json']
],
[
'name' => 'file',
'contents' => fopen('sample.xml', 'r'),
'headers' => ['Content-Type' => 'text/xml']
],
]
]
);
$response = $request->getBody()->getContents();
Also, I'm not sure what the 'name' fields should be ('name' => 'data'), etc.
This is the Guzzle equivalent of your curl command:
$client = new Client(['debug' => true]);
$request = $client->request('POST',
'http://ec2-48-88-173-9.us-east-1.compute.amazonaws.com:8180/rs/process', [
'multipart' => [
[
'name' => 'request',
'contents' => "{'name':'test','reference':870e0320-021e-4c67-9169-d4b2c7e5b9c9}",
],
[
'name' => 'file',
'contents' => fopen('sample.xml', 'r'),
],
]
]
);
$response = $request->getBody()->getContents();
For the file Guzzle will specify the appropriate content type, as curl does. Name for the first part is request — from -F
'request={"name":"test", "reference":"870e0320-021e-4c67-9169-d4b2c7e5b9c9"}'
I'm racking my brains over this - the request goes fine in Postman, but I can't access the body using Guzzle.
$client = new \GuzzleHttp\Client();
$res = $client->request('POST', 'https://apitest.authorize.net/xml/v1/request.api', [
'headers' => [
'Content-Type' => 'application/json',
],
'body' => json_encode([
'createTransactionRequest' => [
'merchantAuthentication' => [
'name' => '88VuW****',
'transactionKey' => '2xyW8q65VZ*****'
],
'transactionRequest' => [
'transactionType' => 'authCaptureTransaction',
'amount' => "5.00",
'payment' => [
'opaqueData' => [
'dataDescriptor' => 'COMMON.ACCEPT.INAPP.PAYMENT',
'dataValue' => $_POST['dataValue']
]
]
]
]
])
]);
dd(json_decode($res->getBody()));
The above returns null - no errors, just null. The below is the same request in Postman, successful with a body.
Any ideas would be really appreciated, thanks!
You should use $res->getBody()->getContents().
And json_decode() returns null in case of any error. You have to check them separately (unfortunately) with json_last_error().
My working Guzzle5 code looks roughly as follows:
$guzzle = new \GuzzleHttp\Client();
$request = $guzzle->createRequest('POST', $url);
$request->setHeader('Authorization', 'Bearer ' . $token);
$postBody = $request->getBody();
$postBody->setField('name', 'content');//several times
if (check for file) {
$postBody->addFile(new \GuzzleHttp\Post\PostFile('name', fopen(...));
}
$response = $guzzle->send($request);
What with setting a header and maybe adding a file, I’m not sure how to do this with Guzzle6.
Here an example from the official documentation how can you set headers and adding file into your POST request with Guzzle 6:
$client = new \GuzzleHttp\Client();
$client->post('/post', [
'multipart' => [
[
'name' => 'foo',
'contents' => 'data',
'headers' => ['X-Baz' => 'bar']
],
[
'name' => 'baz',
'contents' => fopen('/path/to/file', 'r')
],
[
'name' => 'qux',
'contents' => fopen('/path/to/file', 'r'),
'filename' => 'custom_filename.txt'
],
]
]);
The multipart option sets the body of the request to a multipart/form-data form, if you don't need to work with files you can just use form_params instead of multipart option.
Any headers you can easy set with help headers option.
Additional info you can find here Guzzle Upgrade Guide (5.0 to 6.0)
Here is some code copied from one of my projects:
$client = new GuzzleHttp\Client();
$url = 'someurl.com/api';
$body = json_encode([
'variable1' => 'this',
'variable2' => 'that'
]);
$response = $client->post($url, [
'headers' => [
'header_variable1' => 'foo',
'header_variable2' => 'bar'
],
'json' => true,
'timeout' => 3,
'body' => $body
]);
$data = $response->json();
I have this code for sending parameters for a POST request, which works:
$client = new GuzzleHttp\Client();
$request = $client->createRequest('POST', 'http://example.com/test.php');
$body = $request->getBody();
$request->getBody()->replaceFields([
'name' => 'Bob'
]);
However, when I change POST to PUT, I get this error:
Call to a member function replaceFields() on a non-object
This is because getBody is returning null.
Is it actually correct to send PUT parameters in the body? Or should I do it in the URL?
According to the manual,
The body option is used to control the body of an entity enclosing
request (e.g., PUT, POST, PATCH).
The documented method of put'ing is:
$client = new GuzzleHttp\Client();
$client->put('http://httpbin.org', [
'headers' => ['X-Foo' => 'Bar'],
'body' => [
'field' => 'abc',
'other_field' => '123'
],
'allow_redirects' => false,
'timeout' => 5
]);
Edit
Based on your comment:
You are missing the third parameter of the createRequest function - an array of key/value pairs making up the post or put data:
$request = $client->createRequest('PUT', '/put', ['body' => ['foo' => 'bar']]);
when service ise waiting json raw data
$request = $client->createRequest('PUT', '/yourpath', ['json' => ['key' => 'value']]);
or
$request = $client->createRequest('PUT', '/yourpath', ['body' => ['value']]);
If you're using Guzzle version 6 you can make PUT request this way:
$client = new \GuzzleHttp\Client();
$response = $client->put('http://example.com/book/1', [
'query' => [
'price' => '50',
]
]);
print_r($response->getBody()->getContents());
In Guzzle 6, if you want to pass JSON data to your PUT request then you can achieve it as below:
$aObj = ['name' => 'sdfsd', 'language' => 'En'];
$headers = [
"User-Agent" => AGENT,
"Expect" => "100-continue",
"api-origin" => "LTc",
"Connection" => "Keep-Alive",
"accept" => "application/json",
"Host" => "xyz.com",
"Accept-Encoding"=> " gzip, deflate",
"Cache-Control"=> "no-cache",
"verify" => false,
"Content-Type" => "application/json"
];
$client = new GuzzleHttp\Client([
'auth' => ['testUsername', 'testPassword'],
'timeout' => '10000',
'base_uri' => YOUR_API_URL,
'headers' => $headers
]);
$oResponse = $client->request('PUT', '/user/UpdateUser?format=json', ['body' => json_encode( $aObj, JSON_UNESCAPED_SLASHES)]);
$oUser = json_decode( $oResponse->getBody());