Get partial body while guzzle is still downloading it - php

I have a relatively simple guzzle request:
$client = new Client([
'base_uri' => $request_base
]);
$response = $client->request('POST', $request_path, [
'form_params' => ['key' => 'value']
]);
echo $response->getBody();
Right now I'm getting the body when it finishes downloading but I need to get the partial body every few seconds while it is being downloaded.
I looked at the documentation for a while, I'm guessing I have to make an async request but I'm not sure how I would access the partial body.
I can only use php and sockets, besides that I'm open to use another library/piece of code if it will mean a simple solution for this.

Related

Guzzle making a GET request instead of POST

I'm sure this is going to be marked as a duplicate, but I've looked through all the given questions on the same subject and tried many of the suggested solutions, and they haven't worked.
I'm in a laravel project and I have a post request going out through guzzle.
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $url, [
'headers' => [
'Authorization' => 'Bearer ' . $apiToken,
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'allow_redirects' => false,
// 'allow_redirects'=>['strict'=>true]
],
'json' => json_decode($logText, true)
]);
I keep on getting the response back "message": "The GET method is not supported for this route. Supported methods: POST."
I've checked and indeed, it's sending a GET request to the same $url specified above.
I didn't have those allow_redirects settings at first, but both settings were offered up as potential solutions when I googled around. Unfortunately, both options result in the same error message: The GET method is not supported for this route.
Why in the world is my POST request changing to a GET request?
I've also tried $client->post instead, and THAT became a GET request as well.
I've also double checked that the GET error message isn't actually coming from inside the POST request: it's not. The POST route isn't being hit at all.
PHP version 7.2, Laravel version 6.0.2, Guzzle version 6.5.3
Check for redirects on the server, such as HTTP -> HTTPS. Redirects are always a GET request, which will mess up non-GET routing. Using the correct protocol all the way through (such as always use HTTPS) will bypass the redirect.

Async requests with Php Guzzle are not working async

I create the code below to make an async request to get data from an API.
<?php
require 'vendor/autoload.php';
$url = "https://pucminas.instructure.com/api/v1/";
$client = new GuzzleHttp\Client(['base_uri' => $url]);
$headers = [
'Authorization' => "Bearer 11111~dsgffdhstggfjsdhf",
'Accept' => 'application/json',
];
$course_id = "2242";
set_time_limit(300);
$promise = $client->getAsync( 'courses/'.$course_id.'/students/submissions?student_ids[]=all&grouped=true&post_to_sis=false&enrollment_state=active&include[]=user&include[]=assignment&include[]=total_scores&per_page=1000', ['connect_timeout' => 600, 'headers' => $headers]);
$promise
->then(function ($response) {
echo 'Got a response! ' . $response->getStatusCode();
});
?>
<h2>Reports</h2>
I suppose when I load the page it will show the text "Reports" in the page and after getting the content from the API(which needs at least 60 seconds), it will show the message "Got a response", but it won't work that way.
First, the page loads the content from the API and only after that show the text "Reports" and "Got a message" at the same time.
I want the text "Reports" appear instantly when I load the page, and the text "Got a response" only when the data is loaded from the API.
How can I do that?
You can only send a single response from a PHP script i.e. your browser requests a page, the PHP server builds that page and sends it back. The PHP server can't then 'push' an update of the page to your browser as HTTP is stateless.
To achieve the functionality you want you need to write some javascript which will call a PHP script to start the guzzle async promise. This promise would then write the result to a file (or database) when the promise is complete.
You then need a second javascript function which continually checks a second php script. The second PHP script would check the contents of the file (or database entry etc) and return the result.
You might be better to look at something like Axios and lose the PHP altogether
https://www.npmjs.com/package/axios

Guzzle HTTP, can't parse response to JSON

So I'm integrating an API from a 3rd party company and I'm facing this strange situation.
I fetch the endpoint with the following code
$client = $this->client = new Client([
'base_uri' => 'https://xxx.xxxxxxxxxx.com/api/',
'timeout' => 15
]);
$this->requestConfig = [
'auth' => [
'xxxx#xx.xxx',
'xxxxx'
],
'headers' => [
'cache-control' => 'no-cache',
'content-type' => 'application/x-www-form-urlencoded'
],
];
$response = $this->client->get($url, $this->requestConfig);
$content = $response->getBody()->getContents();
Now the fun comes, if I var_dump content I get:
string(66) ""[{\"ExternalId\":\"38\",\"AgencyReference\":\"45436070356676\"}]""
Now I know this response is bad, response type if not set a json, json is URL encoded and everything smells bad.
I've been trying to parse this string for a while.
urldecode doesn't work either.
Question is simple, given a response like that, how can I get a normal array?
Currently using PHP 7.1
So finally found this:
Remove backslash \ from string using preg replace of php
To solve my issue.
In this case it was that the escaped quotes where malforming the json. My final code looks like this.
$response = $response->getBody()->getContents();
$clean = stripslashes($response);
$clean = substr($clean, 1, -1);
dd(json_decode($clean));
Please never write your API's like this...
Just looks awfull
BTW, Content-Type makes sense when you send (in request or response) some content. But you send a GET request, that has no content.
And to specify preferred content type for the response, you should use Accept HTTP header, Accept: application/json for example.
I'm not sure this will solve your problem, but just make things clear and correct ;)

viewing guzzle post request

i would like to see the post request packet before i send it as there is an error in the req and a the api is a general descript 500
error so i cant tell where y request is failing. i mnow the xml is formatted wrong as it works on postman from chrome.
$client = new GuzzleHttp\Client([
'base_uri' => 'https://elstestserver.endicia.com',
]);
$xml = 'changePassPhraseRequestXML=<ChangePassPhraseRequest> <RequesterID>lxxx</RequesterID><RequestID>1263055835</RequestID><CertifiedIntermediary><AccountID>lxxx</AccountID><PassPhrase>dfdsfsd</PassPhrase></CertifiedIntermediary><NewPassPhrase>fdfdsfdsfs</NewPassPhrase></ChangePassPhraseRequest>';
$data = array("ChangePassPhraseXML" => $xml);
$response = $client->post("/LabelService/EwsLabelService.asmx/ChangePassPhraseXML", [
'form_params' => $data
]);
this request works in postman for chrome the heres a working example of the xml
changePassPhraseRequestXML=<ChangePassPhraseRequest><RequesterID>lxxx</RequesterID><RequestID>1263055835</RequestID><CertifiedIntermediary><AccountID>lxxx</AccountID><PassPhrase>dfdsfsd</PassPhrase></CertifiedIntermediary><NewPassPhrase>fdsfdsfds</NewPassPhrase></ChangePassPhraseRequest>
Use Logger middleware
About middlewares for guzzle
Also, 500 error is server fail, not yours.

DELETE request with parameters using Guzzle

I have to do a DELETE request, with parameters, in the CodeIgnitor platform. First, I tried using cURL, but I switched to Guzzle.
An example of the request in the console is:
curl -X DELETE -d '{"username":"test"}' http://example.net/resource/id
But in the documentation of Guzzle they use parameters just like GET, like DELETE http://example.net/resource/id?username=test, and I don't want to do that.
I tried with:
$client = new GuzzleHttp\Client();
$client->request('DELETE', $url, $data);
but the request just calls DELETE http://example.com/resource/id without any parameters.
If I interpret your curl request properly, you are attempting to send json data as the body of your delete request.
// turn on debugging mode. This will force guzzle to dump the request and response.
$client = new GuzzleHttp\Client(['debug' => true,]);
// this option will also set the 'Content-Type' header.
$response = $client->delete($uri, [
'json' => $data,
]);
coming late on this question after having same.
Prefered solution, avoiding debug mode is to pass params in 'query' as :
$response = $client->request('DELETE', $uri, ['query' => $datas]);
$datas is an array
Guzzle V6
$response = json_decode($this->client->delete($uri,$params)->getStatusCode());
echo $response;
This will also give the status of the response as 204 or 404

Categories