PHP Receive JSON POST Data - php

I am trying to receive JSON data from an external system, and then process and save to my local DB. When an event triggers, the external system sends the data below to my system.
The external system logs show:
Log 1: Date/Time: 16 August 2017 11:54:44 AM
Status: Failure
Server: Apache https://blahblah.com/abc/data.php
Status Code: OK
Event Content: [{"field":"_USERNAME","value":""},
{"field":"_PASSWORD","value":""},
{"field":"_TOKEN","value":""},
{"field":"_CODE","value":"L77H4XD6ZA"},
{"field":"_SUBMITTEDDATE","value":"2017.08.16.01.54"},
{"field":"_SUBMITTEDDATEEXT","value":"2017.08.16.01.54.39.610"},
{"field":"_EDITEDDATE","value":"2017.08.16.01.55"},
{"field":"_SEQUENTIALID","value":"39a1cad9-2582-e711-9477-06c7814985cc"},
{"field":"_COMPLETETYPE","value":"Complete"},
{"field":"_LANGUAGE","value":"en"},
{"field":"_TOTALTIME","value":"12.59"},{"field":"_LINKURL","value":"http%3a%2f%2fsurv.blah.com%2ftest3%3fusr%3dL77H4XD6ZA"},
{"field":"GENDER","value":"TEXT%3aFemale%3bVALUE%3a2"},
{"field":"AGE","value":"TEXT%3a40%2b-%2b44%3bVALUE%3a6"},
{"field":"STATE","value":"TEXT%3aVIC%3bVALUE%3a2"},
{"field":"END_CHC","value":"TEXT%3aComplete%3bVALUE%3a2"},
{"field":"D2H","value":""},
{"field":"D2V","value":""},
{"field":"PCODE","value":""},
{"field":"PSTATE","value":""},
{"field":"PREGION","value":""},
{"field":"STATEREGION","value":""},
{"field":"TEST1","value":""}]
So, in my php file (https://blahblah.com/abc/data.php) I have
$json = file_get_contents('php://input');
$obj = json_decode($json);
and I have been trying a foreach() loop to try and get each field and value, to then put into a database, like
foreach($obj as $key => $value)
{
$qry = $conn->prepare('INSERT INTO `key_value`(`db_id`, `rkey`, `rvalue`) VALUES (NULL,$key,$value)');
$qry->execute();
}
But it isn't working, and I either get errors about the foreach loop, or if I play around with just echoing or var_dumping, I get NULL in the response, when I use the Postman or ARC Chrome API testing Apps.
So, I suspect I am on the completely wrong track of how to do this.
Can anyone help guide me back?
EDIT: I have had a look at Receive JSON POST with PHP and a few others, but the working answers aren't clear.

You've got a couple of problems here. First, you need to pass true as the second parameter to json_decode in order to get an associative array instead of a stdClass. Then, when you're iterating the results, you don't need the $key, and the $value is each entry in the results array (each "row"). Try running this to see what's going on:
<?php
$json = <<<JSON
[{"field":"_USERNAME","value":""},
{"field":"_PASSWORD","value":""},
{"field":"_TOKEN","value":""},
{"field":"_CODE","value":"L77H4XD6ZA"},
{"field":"_SUBMITTEDDATE","value":"2017.08.16.01.54"},
{"field":"_SUBMITTEDDATEEXT","value":"2017.08.16.01.54.39.610"},
{"field":"_EDITEDDATE","value":"2017.08.16.01.55"},
{"field":"_SEQUENTIALID","value":"39a1cad9-2582-e711-9477-06c7814985cc"},
{"field":"_COMPLETETYPE","value":"Complete"},
{"field":"_LANGUAGE","value":"en"},
{"field":"_TOTALTIME","value":"12.59"},{"field":"_LINKURL","value":"http%3a%2f%2fsurv.blah.com%2ftest3%3fusr%3dL77H4XD6ZA"},
{"field":"GENDER","value":"TEXT%3aFemale%3bVALUE%3a2"},
{"field":"AGE","value":"TEXT%3a40%2b-%2b44%3bVALUE%3a6"},
{"field":"STATE","value":"TEXT%3aVIC%3bVALUE%3a2"},
{"field":"END_CHC","value":"TEXT%3aComplete%3bVALUE%3a2"},
{"field":"D2H","value":""},
{"field":"D2V","value":""},
{"field":"PCODE","value":""},
{"field":"PSTATE","value":""},
{"field":"PREGION","value":""},
{"field":"STATEREGION","value":""},
{"field":"TEST1","value":""}]
JSON;
$obj = json_decode($json, true);
foreach($obj as $currTuple)
{
echo $currTuple['field'].':'.urldecode($currTuple['value'])."\n";
}
Also some of the results are url encoded, so you'll probably want to decode that before persisting.

Related

Trying to use a JSON API that isn't technically an API

I just started playing D&D, and I'm working on a project for my group to help us play the game a littler easier. We all created Characters on D&D Beyond. They don't have an official API, but apparently, if you type in "your-character-sheet/json" - you can get some JSON output about your character.
I attempted to grab this data in php as I normally would
<?php
$request = "https://www.dndbeyond.com/profile/PixiiBomb/characters/9150025/json";
$url = file_get_contents($request);
$json = json_decode($url, true);
echo $json["character"]["id"];
?>
This should echo out: "9150025" - but I actually see nothing. It's totally blank. So I tried to echo $url, and this is what I see.
Which of course, it not what I should be seeing (because that is formatting from their website, minus the stylesheets)
I went back to the JSON view and manually saved the data as pixii.json This time using the following:
$request = "uploads/dndbeyond_sheets/pixii.json"; // Saved to my harddrive
$url = file_get_contents($request);
$json = json_decode($url, true);
echo $json["character"]["id"];
THIS WORKS if I manually save the file. But that would mean that every time we level up, I would have to manually save all of our JSON data, and run some code to read it and update it.
Is there something else I can try to allow me to use this URL instead of having to manually save the page?
Ideally, I would like to have all of my code written , and then when we level up, I press a button and grab the new data from the site (which I don't need help with, that's not part of the question). Instead of manually visiting each website, saving the data, and then parsing it.

CakePHP 2 requestAction breaks my JSON encoding to Swift... invisibly

I've got CakePHP 2 outputting JSON, and I've got Swift 2 code in the Xcode iPhone emulator loading that JSON data.
In my Controller, here's the code that generates the JSON:
public function iosDemoIndex() {
$studentDataIn = $this->Student->getStudentsByUserId(298, 'rASC');
$studentDataOut = [];
foreach ($studentDataIn as $student) {
//$currentIep = $this->Iep->requestAction('/ieps/getCurrentIep/' . $student['Student']['id']);
$goals = $this->Goal->find('all', array('conditions' => array('Goal.student_id =' => $student['Student']['id'])));
$goalHolder = array();
foreach ($goals as $goal) {
array_push($goalHolder, $goal['Goal']['goal_title']);
}
array_push($studentDataOut, array('studentName' => $student['Student']['l_name']. ", " . $student['Student']['f_name'], 'studentGoals' => $goalHolder));
}
$this->set(array(
'students' => $studentDataOut,
'_serialize' => array('students')
));
}
Which works fine. My Swift code succesfully loads the students array via the JSON into an array of structs. But if I simply un-comment line 5 (which grabs data that I ultimately hope to use to restrict the find in line 6), Xcode gives me:
Error with Json: Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 2." UserInfo={NSDebugDescription=Invalid value around character 2.}
Line 5 shouldn't alter the JSON document in any way. And when I look at the JSON itself, it looks the same regardless of whether the line's commented out.
So, any ideas what an unrelated, ought-to-be invisible requestAction could be doing that's breaking my JSON... in a way that I can't see when I look at it? Thanks.
For posterity (future-me):
It was a login issue. The reason the JSON looked identical in my browser was that I had an active user session in the browser at the time. Without that session, (for instance when the iOS emulator tried to load the JSON page) the CakePHP was returning a redirect to login. Viable solutions include replicating the requestAction code in the JSON-generating controller (though that's not very DRY), or establishing proper login handling on the Swift side of things.

php/json riot api blank page failing

Im new to php and json and usage of API's. Im on a big data project and I want to create a web application that retrieves information from the API in order to create predictive analysis.
I tried to use this code to retrieve data but all I see is a blank page. http://20ff.net/index.php
<html>
<head>
<title>RIOT API SBOX</title>
</head>
<body>
<?php
$json = json_decode(file_get_contents('https://euw.api.pvp.net/api/lol/euw/v2.2/matchhistory/31827832?rankedQueues=RANKED_SOLO_5x5&api_key=key'), true);
var_dump(json_decode($json));
echo $json[0]['firstBloodKill'];
?>
</body>
</html>
Yes, I removed the api key myself, with key its not working also.
Please help me out, are there any basic tutorials how to return information in JSON between php tags?
For reasons that aren't clear to me, it looks like the rankedSoloGamesPlayed field isn't returned for all champions. In fact, in your query it's only returned for a single champion (index 21):
<?php
$KEY = "<Your API Key>";
$url=sprintf('https://euw.api.pvp.net/api/lol/euw/v1.3/stats/by-summoner/31827832/ranked?season=SEASON4&api_key=%s', $KEY);
$data=file_get_contents($url);
$json=json_decode($data);
// Uncomment this if you want to see the full decoded JSON
//print_r($json);
echo $json->champions[21]->stats->rankedSoloGamesPlayed;
// This displays 0, which is the value returned in the JSON
// Additionally, you could access the totalDamageDealt field of the champion with index 0 with:
echo $json->champions[0]->stats->totalDamageDealt;
// This displays 214660
Note how you have to traverse the decoded JSON. If print_r says it's an Array, you can traverse it with brackets ([21]), but if it says it's a stdClass Object, you traverse it with the arrow notation.

LPUSH function in redis (PHP) throwing bool(false) when I get/dump list

Alright, sooooo... The issue is this: I am LPUSH'ing a variable value to a list called "keys". When I try to get and output the value of that list... it claims the list is empty (bool(false)). The syntax seems correct. This code has worked on other occasions (in fact, I am merely going through each function and testing/refactoring/improving what I have already written). I got snagged on this, and I'm completely boggled. Here's the code (with relevant notes):
$kw = $_REQUEST['keyword']; //we're passing a value to this in a query string
if(empty($kw)){
$key = 'default';
createRedis($key);
}else{
$key = $kw;
createRedis($key);
}
function{
$key = $a;
$r = new Redis();
$r->connect( 'localhost' );
$r->LPUSH( 'keys',$key ); // $key echos a value when one is passed in
echo $key; // a query string, BUT....
$keys=$r->get('keys'); //'keys'... the redis list
var_dump($keys); // throws a bool(false) when dumped
}
Is there something crazy that I'm missing? Redis is tested on my server as working. I, otherwise, am unable to sort out what the heck is wrong with this. Here's the documentation on LPUSH for phpredis (which is what we are using (it is also installed and working)): https://github.com/nicolasff/phpredis#lpush
and
the documentation for this on the Redis website (these are CLI examples):
http://redis.io/commands/lpush
Any help is sincerely appreciated. Perhaps I am using an ineffective method to test whether or not the redis list 'keys' is retaining value? (That was the whole purpose of the dump).
You have to use lrange instead of get:
$keys = $r->lrange('keys', 0, -1);

get posterous site_id, php (either preg_match or json_decode?) = no joy

I'm trying to get a user's site_id from posterous. This data seems to be nowhere in the user's profile, and nothing in the FAQ or help or docs indicates how to find this.
The only method I can find is to request a list of sites over API,
So, that's what I'm trying to do, and I get back a json response, and, indeed, the site_id of any site the user has on posterous is in there, and I just want to output this.
First I tried with (where $result is the json response)
$siteid = preg_match('"site_id": \d+', $result);
echo $siteid;
I get nothing.
Then I tried with
json_decode($result);
echo $result->site_id;
I still get nothing.
I can see, in the json response ($result),
"site_id": $somenumber;
Why can't I extract this data with either preg_match or json_decode? Is there another, better method?
My full code is pasted at http://tonybaldwin.me/paste/index.php?3u
The Posterous list-of-sites API returns a list (as you might expect) of mappings. Thus, what you need to do is first pick the right item of the list, and then read it's id key.
$result = json_decode($response);
$first_result = $result[0];
$first_result_id = $first_result["id"];
echo $first_result_id;

Categories