looping through json data from url using php - php

Hi I am attempting to echo out data returned from an api I'm working with utilizing the following code:
<?php
ini_set("include_path", '/home/matthewt/php:' . ini_get("include_path") );
// This sample uses the Apache HTTP client from HTTP Components
(http://hc.apache.org/httpcomponents-client-ga/)
require_once 'HTTP/Request2.php';
$url = $request->getUrl();
$headers = array(
// Request headers
'Ocp-Apim-Subscription-Key' => 'my_id',
);
$request->setHeader($headers);
$parameters = array(
// Request parameters
);
$url->setQueryVariables($parameters);
$request->setMethod(HTTP_Request2::METHOD_GET);
// Request body
$request->setBody("{body}");
try
{
$response = $request->send();
echo $response->getBody();
}
catch (HttpException $ex)
{
echo $ex;
}
Everything up until this point works great and returns json data that basically looks like this: (I shortened the amount of fields to save space)
[{"GameID":49810,"Season":2017},{"GameID":49811,"Season":2017}]
What I need to know is how to loop through this data to print out the results for each game. I know I have to use something like this:
$arr = json_decode();
foreach($arr as $item) { //foreach element in $arr
$game_id = $item['GameID']; //etc
}
But I'm not sure what needs to be decoded...is it $response ?
Thanks

If $response->getBody() contains your json, then json_decode it, then this will be your array of objects which you can loop over.
So try this:
// snip
try
{
$response = $request->send();
$arr = json_decode($response->getBody());
foreach((array) $arr as $item) { //foreach element in $arr
echo $item->GameID; //etc
echo $item->Season; //etc
}
}
catch (HttpException $ex)
{
echo $ex;
}

Related

Async http call with php

I have a situation where I have a loop, that is going to read chunk of data from a file, send those chunk to a rest api, and continue until the EOF, but I want this to be async inside the loop, so, I don't have to wait until the API respond to read the next chunk.
I have been looking at Amphp and ReactPHP for I can't find a solution to this, or maybe I don't understand how are those libraries supposed to be used.
here is a pseudo of what I am doing.
<?php
while($file.read()){
$chunk = getNextChunk();
sendChunkAsync($chunk);
}
function getNextChunk(){
echo "reading next chunk";
// read next chunk of data
}
sample with amphp
function sendChunkAsync($chunk){
Loop::run(function () {
$uri = "https://testapi.com/api";
$client = new DefaultClient;
try {
$promises = $client->request($uri);
$responses = yield $promises;
echo "chunk processed";
} catch (Amp\Artax\HttpException $error) {
// log error
// $error->getMessage() . PHP_EOL;
}
});
}
In this case I would expect (if reading chunk is faster than getting response from api) something like this, don't take this literary, I am trying to illustrate it for you.
Reading next chunk
Reading next chunk
chunk processed
Reading next chunk
chunk processed
chunk processed
I am going to use React as I know the library better but they work in similar ways.
EDIT: updated, see comments
This will read in a file and every time it recieves a chunk of data, it will create an api call and send the data off
<?php
require_once __DIR__ . '/vendor/autoload.php';
function async_send($config, $file, callable $proccessor)
{
$config['ssl'] = true === $config['ssl'] ? 's' : '';
$client = new \GuzzleHttp\Client([
'base_uri' => 'http' . $config['ssl'] . '://' . $config['domain'] . '/rest/all/V1/',
'verify' => false,
'http_errors' => false
]);
$loop = \React\EventLoop\Factory::create();
$filesystem = \React\Filesystem\Filesystem::create($loop);
$filesystem->getContents($file)->then(function($contents) use ($config, $proccessor, $client) {
$contents = $proccessor($contents);
$client->post($config['uri'], ['body' => $contents]);
});
}
$config = [
'domain' => 'example.com',
'ssl' => true
];
//somewhere later
$configp['uri'] = 'products';
async_send($configp, __DIR__ . 'my.csv', function ($contents) {
return json_encode($contents);
});
In case someone else is trying to solve a similar problem
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use React\HttpClient\Client as ReactClient;
function async_send($loop, $filePath, callable $proccessor)
{
echo "starting";
echo "\n\r";
try {
$filesystem = \React\Filesystem\Filesystem::create($loop);
$file = $filesystem->file($filePath);
$file->open('r')
->then(function ($stream) use ($loop, $proccessor){
$stream->on('data', function ($chunk) use ($loop, $proccessor) {
$proccessor($chunk);
});
});
} catch (\Exception $e) {
echo "failed";
echo "\n\r";
}
echo "ending reading";
echo "\n\r";
}
function callApiReal($loop, $fileChunk = null)
{
echo "ready to call api". PHP_EOL;
$uri = "https://testapi.com/";
try {
$client = new ReactClient($loop);
} catch (\Exception $e) {
echo "Error";
}
echo "ready to call api";
$request = $client->request('POST', $uri, $fileChunk);
$request->on('response', function ($response) use ($uri) {
$response->on('data', function ($data_chunk) {
echo 'data chunk from api received';
echo "\n\r";
});
// subscribe to listen to the end of the response
$response->on('end', function () use ($uri) {
echo "operation has completed";
echo "\n\r";
});
});
$request->on('error', function ($error) {
// something went bad in the request
echo "Damm!";
echo "\n\r";
});
$request->end();
}
// main loop
$loop = React\EventLoop\Factory::create();
//somewhere later
async_send($loop, __DIR__ . '/my.csv', function ($chunk) use ($loop) {
echo "calling api";
callApiReal($loop, $chunk);
echo "\n\r";
});
$loop->run();

How to call soap web service from php

I am able to consume soap web service using wizdler in my chrome but need to how can I consume it in my php code.
From Wizdler I can get the proper response, for example I am posting the information like this:
Question is how to call this service from php code, what I did/trying so far is:
<?php
$wsdl = "http://64.20.37.90/VTWebServiceTest/VisualService.svc?wsdl";
$client = new SoapClient($wsdl);
$request_param = array(
"storeNumber" => "valid value",
"enterpriseId" => "valid value",
"credential" => "valid value"
);
try {
$responce_param = $client->GetCategories($request_param);
$result = $responce_param->GetCategoriesResult;
print_r($result);
} catch (Exception $e) {
echo "Exception Error!";
echo $e->getMessage();
}
?>
But it always returns message "12|Invalid service credential."
Can anybody help me out?
Thanks in advance.
maybe try this ...
$responce_param = $client->GetCategories($request_param);
print_r($responce_param);
or even
$responce_param = $client->GetCategories($request_param);
$values = get_object_vars($responce_param);
$myresults = object_to_array($values);
print_r($myresults);

php rest API POST request returning null

I've created a REST API base on this tutorial - note that I am a newbie in php and REST...
Now, I am stuck when calling a POST request. The main return function is as follows:
// Requests from the same server don't have a HTTP_ORIGIN header
if (!array_key_exists('HTTP_ORIGIN', $_SERVER)) {
$_SERVER['HTTP_ORIGIN'] = $_SERVER['SERVER_NAME'];
}
try {
$API = new MyAPI($_REQUEST['request'], $_SERVER['HTTP_ORIGIN']);
$res = $API->processAPI();
echo $res; // contains my json as expected
return $res; // always empty string
} catch (Exception $e) {
echo "Exception: " . json_encode(Array('error' => $e->getMessage()));
}
EDIT
I've just tried something even simpler in the API caller method, namely following:
try {
$res = json_encode(Array('test' => "my message"));
// comment out one or the other to check output...
//echo $res;
return $res;
} catch (Exception $e) {
echo "Exception: " . json_encode(Array('error' => $e->getMessage()));
}
Result with echo is (the way I get responese is below... exact response is between # characters):
#{"test":"my message"}#
Result with return is
##
EDIT 2
Here is how I call the API from C#:
using (HttpClient client = new HttpClient()) {
JObject jo = new JObject();
jo.Add("usr", "username");
jo.Add("pwd", "password");
Uri url = new Uri(string.Format("{0}/{1}", RestUrl, "login"));
StringContent content = new StringContent(jo.ToString(), Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(url, content);
bool isOk = response.StatusCode == System.Net.HttpStatusCode.OK;
// this is where I get the result from...
var res = response.Content.ReadAsStringAsync().Result;
}
I really don't understand this - could someone please explain in non-php expert terms??

Guzzle and Unable to parse response into JSON

I have a little php api client with this method:
private function send($endpoint)
{
$headers = array();
$body = $this->xmlSerialiser->convertToXML($this->getQueue());
try {
$response = json_decode(
$this->guzzleClient->post(
$endpoint,
$headers, $body
)
->send()
->json()
);
} catch (\Guzzle\Http\Exception\BadResponseException $e) {
$response = array('Error' => $e->getMessage());
}
return $response;
}
I'm always receiving
Unable to parse response body into JSON: 4 (500 Internal Server Error)
I already tried to know an example of server response and seems to be fine:
echo (string) $this->guzzleClient->post(
$endpoint,
$headers, $body
)
->send()->getBody();
and this is the result:
<Messages xmlns="http://www.example.com/xxx/3.0">
<GetAccountResponse RequestType="GetAccount">
<AccountId>xxxx-xxx-xxx-xxxx-xxxx</AccountId>
<Token>xxxxxxxxxxxxxx/t3VkEJXC7f6b6G4yPJSZ5QfT2hdSQXUmi0e8cndSYLK4N7mswRHifzwGHLUJYHM17iGL8s=</Token>
</GetAccountResponse>
I answered myself
the Guzzle documentation says: json method -> Parse the JSON response body and return an array
so in my case I need to switch the json mehod to xml (cos the response is an xml).
Finally this is the result:
private function send($endpoint)
{
$headers = array();
$body = $this->xmlSerialiser->convertToXML($this->getQueue());
try {
$response = (array)(
$this->guzzleClient->post(
$endpoint,
$headers, $body
)
->send()
->xml()
);
} catch (\Guzzle\Http\Exception\BadResponseException $e) {
$response = array('Error' => $e->getMessage());
}
return $response;
}
Use following code.
$response->getBody()->getContents()

PHP SOAP issue feeding in results

I'm trying to create a page that displays current results from CA Lottery using PHP. I've used XML before, but am having issues with SOAP. I found this page, but its not a lot of help.
I've put together the code below, and was able to get it to return an object. But I can't get it to feed in the results I need. Any help would be amazing.
try {
$options = array(
'soap_version'=>SOAP_1_1,
'exceptions'=>true,
'trace'=>1,
'cache_wsdl'=>WSDL_CACHE_NONE
);
$client = new SoapClient('http://services.calottery.com/CALotteryService.asmx?WSDL', $options);
} catch (Exception $e) {
echo "<p>Exception Error!</p>";
echo $e->getMessage();
}
echo '<p>Connection: Success;</p>';
try {
$response = $client->GetCurrentGameInfo();
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
$x = simplexml_load_string("<?xml version=\"1.0\"?>".$response->GetCurrentGameInfoResult->any);
var_dump($x);
Try this
var_dump($response);
$x = simplexml_load_string("<?xml version=\"1.0\"?>".$response->GetCurrentGameInfoResult->any);
var_dump($x);
at the end of your script. Kind of odd, but calottery is returning a fragment of XML in the response that needs to be further processed ( the simplexml_load_string ).

Categories