Trouble getting Google Books API data via PHP - json

The current code takes form input and does THIS to it:
$apikey = 'myapikey';
$q = urlencode($bookSearchTerm);
$endpoint = 'https://www.googleapis.com/books/v1/volumes?q=' . $q . '&key=' . $apikey;
$session = curl_init($endpoint);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($session);
curl_close($session);
$search_results = json_decode($data);
if ($search_results === NULL) die('Error parsing json');
Just for kicks, I also did
echo $endpoint;
which shows
https://www.googleapis.com/books/v1/volumes?q=lord+of+the+rings&key=myapikey
When I enter that URL into a browser, I get a screen full o' data, telling me that, among other things, there are 814 items.
Yet when I run the code on a page, I get
Error parsing json
Can someone show me where I'm going wrong?
Thanks in advance.

By the response to the comment, it could be set, maybe not. It may also be the case that what is returned isn't parse-able by the parser because it isn't in the right data format. Check what $data gives back as a result. If it's correct then by the json_decode doc on the PHP site it may be that it's simply too big for the parser to parse (reaches recursion limit) though I doubt that.
It it is possible that the what is return just overflows the PHP allocated memory limit. PHP parses JSON into associative or numbered arrays, which can get expensive. So if what you get back is just too big, it'll fail to finish parsing and just return null.

Related

json_decode problems in php

i use json_decode function to get some data from dynamic urls.
some urls are working fine inside the decode function, others are not.
for example:
this is working fine:
$jsondata = file_get_contents("http://185.112.249.77:9999/Api/Search?search=&level=1&min=1&max=50&points=48000");
$data = json_decode($jsondata, true);
but when i change the 48000 to 45000, the decode is not working any more.
41000 is working fine again.
also.. when i add some other attributes after the points-attribute... the decode function does also not work anymore.
for example:
$jsondata = file_get_contents("http://185.112.249.77:9999/Api/Search?search=&level=1&min=1&max=50&points=20000&loc=32000007");
$data = json_decode($jsondata, true);
when i remove &loc=32000007 it works again.
when you use direct the urls in the browser, all of them are working.
only the json_decode function is not working with some of them.
is there any limitation in the characters which you can use inside the json_decode function? is there any way to handle this?
your help is much appreciated.
ok. i managed to get this problem solved.
here is one simple solution which can be adapted according to the requirements.
all characters which are listed inside the array will be replaced by character "?"
$jsondata = file_get_contents($url);
$tobecleaned = array("®");
$jsondatacleaned = str_replace($tobecleaned, "?", $jsondata);
$data = json_decode($jsondatacleaned, true);

Perl: Accessing part of a JSON query

I have been writing part of a website I'm making, part of the stats page will display information about a websites Json response.
The address of the website is: http://steamcommunity.com/market/listings/440/Name%20Tag/render/?count=1&start=1&query=.
Here is a link to a parser so the code is easier to read http://json.parser.online.fr/.
The code I have written so far works but no matter what i try I cant get the information I need.
use JSON::XS;
use WWW::Mechanize;
use HTTP::Cookies;
use LWP::Simple;
use strict;
use warnings;
my $url = "http://steamcommunity.com/market/listings/440/Name%20Tag/render/?count=2&start=2";
my $json = get $url;
my $data = decode_json $json;
my $info = $data -> {listinginfo};
My problem is that i would like to access the price of the listing however when new listings are made available the reference for them changes. I have no idea how to deal with this and Google is not helping. Any help would be greatly appreciated, thanks in advance.
Seb Morris.
EDIT: Thanks for the replies, I have progressed my code and ended up with:
my $data = decode_json $json;
my #infoids = keys %{$data -> {listinginfo}};
foreach my $infoid (#infoids) {
my $price = $data -> {listinginfo}{$infoid}{converted_price};
print "$price" . "\n";
}
However I am getting the error: Use of uninitialized value $price in string at line 30. I dont understand why I am getting this error as I have declared the variable. Any help would be really appreciated.
If I understand, your problem is that the listinginfo object contains key(s) which change for each request, and you don't know to find out what the key is for the request you just made.
You can find the keys to a perl hash using the 'keys' function. So you can get all of the keys of the listinginfo hash like this:
my #infoids = keys %{$data -> {listinginfo}};
Note the need to use %{ } to de-reference listinfo, which is itself a hash reference.
There could be more than one info ID, although when I tested the web service you linked in your question it only ever returned one. If you are sure there will only ever be one, you can use:
my $price = $data -> {listinginfo}{$infoids[0]}{price};
Or, if there might be more than one, you can loop through them:
foreach my $infoid (#infoids) {
my $price = $data -> {listinginfo}{$infoids[0]}{price};
# Now do something with price
}

Why can't I compute a correct HMAC signature?

I am trying to compute an HMAC signature in Google Apps Script, but the documentation isn't 100% clear on how I need to pass in the parameters, and I have been unable to get the expected output.
To determine if I am getting correct output, I am comparing the result against known-good PHP code. That code is:
$key = "a2V5"; # this is "key" base64-encoded
$value = "test";
$result = base64_encode(hash_hmac('sha512', $value, base64_decode($key), true));
My code in Google Apps Script is:
key = "a2V5"; // this is "key" base64-encoded
value = "test";
result = Utilities.base64Encode(Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, value, Utilities.base64Decode(key)));
The output I expected to receive was:
KHoPuJp/vfpbVThjaRjlN6W4MGXk/zMSaLeqoRXd4EepsPT7W4KGCPwLYyfxAFX3Y3sFjp4Nu55piQGj5t1GHA==
But what I got instead was:
mGXJ3X/nH5ZIFUAPtf1PsViY50pD3cfU7J8w2KAIEAqrAgZ3dpKcuy5V1yvH4/C5n1C9rFFsKc2JKHTwUqPscQ==
What did I screw up here?
I reviewed your code and there is one thing which caught my eye:
Utilities.base64Decode(key) method returns Byte[]
Utilities.computeHmacSignature(macAlgorithm, value, key) accepts 3 parameters. value and key are of type string.
Maybe this is the issue. Why don't you try something like the following and check results then:
key = "a2V5"; // this is "key" base64-encoded
clearKey = "key";
value = "test";
result = Utilities.base64Encode(Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, value, clearKey));
I check Google Apps Script here.

Problems parsing Reddit's JSON

I'm working on a perl script that parses reddit's JSON using the JSON module.
However I do have the problem of being very new to both perl and json.
I managed to parse the front page and subreddits successfully, but the comments have a different structure and I can't figure out how to access the data I need.
Here's the code that successfully finds the "data" hash for the front page and subreddits:
foreach my $children(#{$json_text->{"data"}->{"children"}}) #For values of children.
{
my $data = $children->{"data"}; #accessing each data hash.
my %phsh = (); #my hash to collect and print.
$phsh{author} = $data->{"author"};#Here I get the "author" value from "data"
*Etc....
This successfully gets what I need from http://www.reddit.com/.json
But when I go to the json of a comment, this one for example, it has a different format and I can't figure out how to parse it. If I try the same thing as before my parser crashes, saying it is not a HASH reference.
So my question is: How do access the "children" in the second JSON? I need to get both the data for the Post and the data for the comments. Can anybody help?
Thanks in advance!
(I know it may be obvious, but I'm running on very little sleep XD)
You need to either look at the JSON data or dump the decoded data to see what form it takes. The comment data, for example is an array at the top level.
Here is some code that prints the body field of all top-level comments. Note that a comment may have an array of replies in its replies field, and each reply may also have replies in turn.
Depending on what you want to do you may need to check whether a reference is to an array or a hash by checking the value returned by the ref operator.
use strict;
use warnings;
binmode STDOUT, ':utf8';
use JSON;
use LWP;
use Data::Dump;
my $ua = LWP::UserAgent->new;
my $resp = $ua->get('http://www.reddit.com/r/funny/comments/wx3n5/caption_win.json');
die $resp->status_line unless $resp->is_success;
my $json = $resp->decoded_content;
my $data = decode_json($json);
die "Error: $data->{error}" if ref $data eq 'HASH' and exists $data->{error};
dd $data->[1]{data}{children}[0];
print "\n\n";
my $children = $data->[1]{data}{children};
print scalar #$children, " comments:\n\n";
for my $child (#$children) {
print $child->{data}{body}, "\n";
}

Query only working on PHPMyAdmin

I'm trying this query:
//connect;
$site = mysql_real_escape_string($_GET['site']);
$data = mysql_query("SELECT * FROM Items WHERE Site = '$site'");
while($row = mysql_fetch_array( $data ))
{
print $row['type'];
}
doesn't print anything, running SELECT * FROM Items WHERE Site = 'http://rollingstone.com/' from PHPMyAdmin returns one row.
I'm sure it must be something really basic, since I haven't got much experience with MySQL.
I'm trying it here btw: http://www.chusmix.com/game/insert/get-items.php?site=http://rollingstone.com/
What am I doing wrong?
Make sure $site actually contains something; doing a quick echo $site before your mysql_query() should tell you this. If it's empty, try print_r($_GET) to see if it's in the $_GET array. It should be, but it might not for some other reason; check any code above this snippet for stuff that modifies $_GET or $_REQUEST in any way.
To request data from a MySQL table, you need to connect to the server using mysql_connect(), then select the database with mysql_select_db(). PHP should throw errors, but to be sure put these lines at the top of your script:
error_reporting(E_ALL);
ini_set('display_errors', '1');
All errors will now be shown.
In addition, you can also test for how many rows that were returned using mysql_num_rows(). For example:
if(mysql_num_rows($data) !== false)
{
while(...)
{
...
}
}
else
{
echo "No rows";
}
Will echo No rows if there weren't any results from the query. This is all error detection code; the cause of your error isn't obvious, so a little investigation is necessary, using the above methods (and any more you can think of).
Have you called mysql_select_db('your_database_name'); on the connection first? Have you tried echoing out the SQL before it's executed to confirm that Site is what you expect it to be?
$query = sprintf("SELECT * FROM Items WHERE Site ='%s'",
mysql_real_escape_string($site));
$result = mysql_query($query);
Just to be on the safe side (avoid SQL Injections).