How can I create an asynchronous request to multiple URI with different post data for each?
I am able to get the data for each of the URI, but I want to make it asynchronous.
Also, how do I timeout if the request takes too long?
My code:
//url
$ur1 = 'www.exaample1.com';
$ur2 = 'www.Test.com';
//xml
$ur1_xml = ''; // xml code
$ur2_xml = ''; // xml code
//headers
$ur1_header = array("POST HTTP/1.1",
"Content-type: application/xml; charset=\"utf-8\"",
"Content-length: " . strlen($ur1_xml));
$ur2_header = array("POST HTTP/1.1",
"Content-type: application/xml; charset=\"utf-8\"",
"Content-length: " . strlen($ur2_xml));
$client = new Client();
// make request
$request = new Request('POST', $ur1_url, $ur1_headers,$ur1_xml);
$promise = $client->sendAsync($request)->then(function ($response) {
echo '<pre>';
print_r(simplexml_load_string($response->getBody()));
echo '</pre>';
});
die();
For application/x-www-form-urlencoded send Async requests you can get benefit from Guzzle promises. Headers and POST fields should go into an array as documents state.
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
.
.
.
$client = new Client();
$promises = [
$client->postAsync($url1, ['headers' => $headers1, 'form_params' => $postData1]),
$client->postAsync($url2, ['headers' => $headers2, 'form_params' => $postData2]),
$client->postAsync($url3, ['headers' => $headers3, 'form_params' => $postData3])
];
$results = Promise\unwrap($promises);
$results = Promise\settle($promises)->wait();
// response headers of first request
print_r($results[0]['value']->getHeaders());
// retrieved contents of second request
echo $results[1]['value']->getBody()->getContents();
Related
I'm learning to use an API. They provide an example of the following authentication code:
curl -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d " {\"Username\": \"the_username\",
\"Password\": \"the_password\"}
" "https://someurl.someapi.com:443/api/Login/Authenticate"
However I need to reproduce this with a Guzzle request. Here is what I've been trying
$headers = [
"Content-Type" => "application/json",
"Accept" => 'application/json -d " {\"Username\": \"the_username\", \"Password\": \"the_password\" }" ',
];
// $headers = [
// "Content-Type" => "application/json"
// ];
$extra_data = ["proxy" => $proxy,
"headers" => $headers ];
// Defining the Guzzle Client to communicate with Legacy.com
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://someurl.someapi.com:443/api/Login/Authenticate',
// You can set any number of default request options.
'timeout' => 10.0,
]);
try {
$response = $client->request('POST', '', $extra_data);
}
However no matter what I try (this was the latest of my failed attempts), I can't get anything other than a code 400 error.
So I finally figured how to do this:
This code worked!
$str = json_decode('{ "Username": "' . $username . '", "Password": "' . $password . '"}',true);
var_dump($str);
if ($str == NULL) return;
$url_authenticate = "Login/Authenticate";
$extra_data = ["proxy" => $proxy,
"json" => $str ];
// Defining the Guzzle Client to communicate with Legacy.com
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://someurl.someapi.com:443/api/',
// You can set any number of default request options.
'timeout' => 10.0,
]);
try {
$response = $client->request('POST', $url_authenticate, $extra_data);
}
catch (Exception $e) {
echo 'Exception: ' . $e->getResponse()->getStatusCode() . "\n";
exit;
}
$body = $response->getBody();
echo $body;
The key was use the json field int the extra data and transform the json to php array using json_decode. I hope this helps someone else
I am using this code to establish a new connection on user device.
var socket = new WebSocket("wss://cdsbxtx2xi.execute-api.us-east-2.amazonaws.com/test");
socket.onmessage = function (event) {
json = JSON.parse(event.data);
connectionId = json.connectionId;
document.cookie = "connection_id="+connectionId;
console.info(json);
}
Suppose from this request I get connectionId CLO5bFP1CYcFSbw=
Another user from another device also established a new connection with connectionId Cs42Fs5s5yuSbc=. Now how can I send a message from user 2 device to user 1?
I already tried this. I don't know this is right way or not but still, i am open for any suggestion.
use Aws\Signature\SignatureV4;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Aws\Credentials\Credentials;
$client = new GuzzleHttp\Client();
$credentials = new Credentials("XXXXXXXXXX","XXXXXXXX");
$url = "https://cdsbxtx2xi.execute-api.us-east-2.amazonaws.com/test/#connections/CLO5bFP1CYcFSbw=";
$region = 'us-east-2';
$msg['action'] = 'sendmessage';
$msg['data'] = 'hello world';
$msg = json_encode($msg);
$request = new Request('POST', $url, '["json"=>$msg]');
$s4 = new SignatureV4("execute-api", $region);
$signedrequest = $s4->signRequest($request, $credentials);
$response = $client->send($signedrequest);
echo $response->getBody();
This code keeps on loading and finally throws gateway timeout error.
I expect that user 2 should be able to send message to any specific connectionId over wss or https.
I tried https by signing this request but signing doesn't works. I am getting an error with the signing part
After struggling with this problem for the last 3 days finally I found the solution. None of the previously mentioned solutions on StackOverflow was working for me.
This is the correct solution. I hope this will be helpful to someone.
use Aws\Signature\SignatureV4;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Aws\Credentials\Credentials;
$client = new GuzzleHttp\Client();
$credentials = new Credentials(accessKeyId, secretAccessKey);
$url = "https://xsdsdsd.execute-api.us-east-2.amazonaws.com/test/#connections/CNtBveH2iYcCKrA=";
// CNtBveH2iYcCKrA= is connectionid
$region = 'us-east-2';
$msg['action'] = 'sendmessage';
$msg['data'] = 'hello world';
$msg = json_encode($msg);
$headers = array('Content-Type => application/x-www-form-urlencoded');
$request = new GuzzleHttp\Psr7\Request('POST', $url, ['Content-Type' => 'application/json'], $msg);
$signer = new Aws\Signature\SignatureV4('execute-api', $region);
$request = $signer->signRequest($request, $credentials);
$headers = array('Content-Type => application/x-www-form-urlencoded');
$client = new \GuzzleHttp\Client([ 'headers' => $headers]);
$response = $client->send($request);
$result = $response->getBody();
Hey you can use the Connection URL to send message also.
Connection url : https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/#connections
To find go to : Aws console > Api gateway > api > your_api > dashboard their you will find your connection url.
Use php cURL method because its easy and fast as compare to GuzzleHttp
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/#connections/{YOUR_CONNECTION_ID_OF_USER}',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{"message" : "Hello world"}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
I am new to PHP, I am using Guzzle client to make a Rest Call and also adding request header using $_SERVER variable.
But in my request call, sometimes the user sends a Header(x-api-key) and sometimes there is no header. When a header is not sent in request my PHP Guzzle throws an error,
Notice: Undefined index: HTTP_X_API_KEY in Z:\xampp\htdocs\bb\index.php on line 16
<?php
require './vendor/autoload.php';
$client = new \GuzzleHttp\Client();
$res = $client->request('GET', 'http://s.com',[
'headers' => [
'User-Agent' => $_SERVER['HTTP_USER_AGENT'],
'x-api-key' => $_SERVER['HTTP_X_API_KEY']
]
]);
$json = $res->getBody();
echo $json;
$manage = json_decode($json, true);
echo $manage;
?>
How can I make this x-api-key header optional and not triggering the PHP error.
You can set the headers individually, checking conditions in which each of them are to be added beforehand:
require './vendor/autoload.php';
$client = new \GuzzleHttp\Client();
$headers = array();
$headers['User-Agent'] = $_SERVER['HTTP_USER_AGENT'];
if(isset($_SERVER['HTTP_X_API_KEY'])){
$headers['x-api-key'] = $_SERVER['HTTP_X_API_KEY']; // only add the header if it exists
}
$res = $client->request('GET', 'http://s.com',[
'headers' => $headers
]);
$json = $res->getBody();
echo $json;
$manage = json_decode($json, true);
echo $manage;
?>```
Could you help me I'm studying about cognitive services using the azure service, but I'm having some mistakes using the forncecido model in the documentation
<?php
// This sample uses the Apache HTTP client from HTTP Components (http://hc.apache.org/httpcomponents-client-ga/)
require_once 'HTTP/Request2.php';
// Replace <Subscription Key> with a valid subscription key.
$ocpApimSubscriptionKey = '98471c5c832e466688890f6c86f6c88d';
$request = new Http_Request2('https://brazilsouth.api.cognitive.microsoft.com/face/v1.0/facelists/{faceListId}');
$url = $request->getUrl();
$headers = array(
// Request headers
'Content-Type' => 'application/json',
'Ocp-Apim-Subscription-Key' => $ocpApimSubscriptionKey ,
);
$request->setHeader($headers);
$parameters = array(
// Request parameters
'faceListId' => 'sahara'
);
$url->setQueryVariables($parameters);
$request->setMethod(HTTP_Request2::METHOD_PUT);
// Request body
$request->setBody("{body}");
try
{
$response = $request->send();
echo $response->getBody();
}
catch (HttpException $ex)
{
echo $ex;
}
?>
I run this script in php and it gives me the following error
{"error":{"code":"BadArgument","message":"Request body is invalid."}}
could you tell me what I'm doing wrong, please
According to the FaceList - Create API, the body format is
{
"name": "sample_list",
"userData": "User-provided data attached to the face list."
}
We need to send body with following way, then it should work.
// Request body
$request->setBody('{"name":"facelistName","userData":"it is optional"}'); //replace it with your name and userData
If want to reference 'HTTP/Request2.php';, we need to install http_request2
pear install http_request2
How to install the PEAR package manager, please refer to this link.
Demo code:
<?php
// This sample uses the Apache HTTP client from HTTP Components (http://hc.apache.org/httpcomponents-client-ga/)
require_once 'HTTP/Request2.php';
$request = new Http_Request2('https://xxx.api.cognitive.microsoft.com/face/v1.0/facelists/{faceListId}');
$url = $request->getUrl();
$headers = array(
// Request headers
'Content-Type' => 'application/json',
'Ocp-Apim-Subscription-Key' => 'xxxxxxxxxx', //replace it with your key
);
$request->setHeader($headers);
$parameters = array(
'faceListId' => 'facelistId'
);
$url->setQueryVariables($parameters);
$request->setMethod(HTTP_Request2::METHOD_PUT);
// Request body
$request->setBody('{"name":"facelistName","userData":"it is optional"}');//replace it with your name and userData
try
{
$response = $request->send();
echo $response->getBody();
}
catch (HttpException $ex)
{
echo $ex;
}
?>
I am using Google Tracks API to build a simple web based program to track a vehicle that has a tracking device sending latitude and longitude coordinates.
I am using PHP and the OAuth2 PHP library to make an authorized connection.
After authorizing and getting an access token I am making a request to create entities. Though I can't seem to get this working and keep getting a "400 Bad Request" response. Following all the steps shown in the documentation.
Here is my code:
$url = 'https://www.googleapis.com/tracks/v1/entities/create/?access_token='.$parsedAuth['access_token'];
$data = array('entities' => array( "name"=> "Chevrolet" ));
$json_data = json_encode($data);
$data_length = http_build_query($data);
$options = array(
'http' => array(
'header' => "Content-type: application/json\r\n". "Content-Length: " . strlen($data_length) . "\r\n",
'method' => 'POST',
'content' => $json_data
),
);
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
var_dump($response);
Exact Error is: "failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request"
Why am I getting a bad request? What would be a good request that will register these entities and return id's?
Thank you
The answer given here is wrong. The documentation states that it must be a POST see here My issue was not with the Auth but with the Tracks API itself. I ended up moving to create the request with CURL and it works just fine.
Please. This is PHP with CURL. It works 100%.
//Google maps tracks connection
//Get Files From PHP Library
require_once 'google-api-php-client/src/Google/autoload.php';
require_once 'google-api-php-client/src/Google/Service/MapsEngine.php';
//Set Client Credentials
$client_id = '*************.apps.googleusercontent.com'; //Client ID
$service_account_name = '************#developer.gserviceaccount.com'; //Email Address
$client_email = '*************#developer.gserviceaccount.com';
$private_key = file_get_contents('************.p12');
$scopes = array('https://www.googleapis.com/auth/tracks');
//Create Client
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
//Send Credentials
$credentials = new Google_Auth_AssertionCredentials(
$client_email,
$scopes,
$private_key
);
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($credentials);
}
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$client->setAssertionCredentials($credentials);
$_SESSION['service_token'] = $client->getAccessToken();
foreach ($_SESSION as $key=> $value) {
$vars = json_decode($value);
}
$parsedAuth = (array) $vars;
$token = $parsedAuth['access_token'];
//all functions in the program use this auth token- It should be global for easy accesses.
global $token;
function createEntities(){
global $token;
$url = 'https://www.googleapis.com/tracks/v1/entities/create/?access_token='.$token;
//FIX ME: fields is temporarily hard coded- should be brought from DB
$fields = array(
'entities' => array(
'name' => "DemoTruck",
'type' => "AUTOMOBILE"
),
);
//json string the data for the POST
$query_string = '';
foreach($fields as $key => $array) {
$query_string .= '{"' . urlencode($key).'":[{';
foreach($array as $k => $v) {
$query_string .= '"' . urlencode($k) . '":"' . urlencode($v) . '",';
}
}
$str = rtrim($query_string , ',');
$fstr = $str.'}]}';
$length = strlen( $fstr );
//open connection
$ch = curl_init();
//test connection
if (FALSE === $ch)
throw new Exception('failed to initialize');
//set options
$header = array('Content-type: application/json');
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_HTTPHEADER, $header);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fstr);
$result = curl_exec($ch);
//dump in case of error
if (FALSE === $result){
var_dump( curl_error($ch) );
var_dump( curl_getinfo($ch) );
}
//close connection
curl_close($ch);
}