I am trying to get information by json_decode from Google maps API, but for some reason I get a strange output. Can someone help me with this?
$request = file_get_contents ('https://maps.googleapis.com/maps/api/geocode/json?address=meerpaal%208d%20oosterhout&sensor=true');
$data = json_decode( $request, true );
foreach ( $data['results'][0]['geometry'] as $value ) {
echo $value['lat'] . '<br />';
echo $value['lng'] . '<br />';
}
This is my output:
51.6303446
4.8655305
R
R
It looks like the script takes the first letter of:
"location_type" : "ROOFTOP",
what comes next if you watch this: https://maps.googleapis.com/maps/api/geocode/json?address=meerpaal%208d%20oosterhout&sensor=true
I don't need the 2 R's.. Does anyone know what I am doing wrong?
EDIT:
var_dump($data['results'][0]['geometry'])
Array
(
[location] => Array
(
[lat] => 51.6303446
[lng] => 4.8655305
)
[location_type] => ROOFTOP
[viewport] => Array
(
[northeast] => Array
(
[lat] => 51.631693580291
[lng] => 4.8668794802915
)
[southwest] => Array
(
[lat] => 51.628995619708
[lng] => 4.8641815197085
)
)
)
Late to the party, but I wanted to add what has worked for me as I searched high and low early on with Google Maps and how to dynamically collect lat and long much the way the OP has described. Please correct me if I am incorrect as I am still learning PHP and Google Maps in general, but again, this code works for my needs and I wanted to share this with the OP and others that may be searching for examples of working code that fits the OPs criteria.
I created this function after much banging of head to keyboard, this works for me in PHP 7. I see no need for a loop if you are collecting one addresses geo location.
Simply decode your http request from google api, check the request for validation, then assign the values of the lat and long to variables to be used as needed in your application/project.
I have included an example of how I collect Lat and Long of customers that sign up through a form with a simple street address.
*#NOTE: I have not shown any example of cleaning the posted variables in this answer. Please make sure to clean your posts of unwanted html entities/slashes/empty spaces, etc... *
function get_lat_and_long($address){
// $address = The address string in a proper address format, we run through urlencode();
// Get JSON results from this request
// APIKEY = *Google API personal key* and is a constant coming from an external constants.php file.
// You can add your key statically though I recommend saving all sensitive variables/constants and arrays in a server side file that has no access by regular users.
$geo = file_get_contents('https://maps.googleapis.com/maps/api/geocode/json?address='.urlencode($address).'&sensor=false&key='.APIKEY);
// Convert JSON and validate
$geo = json_decode($geo, true);
if ($geo['status'] == 'OK') {
// Get Lat & Long
$latitude = $geo['results'][0]['geometry']['location']['lat'];
$longitude = $geo['results'][0]['geometry']['location']['lng'];
}else{
$latitude = NULL;
$longitude = NULL;
}
return $latitude;
return $longitude;
}
Without a function...
//create string holding address to run through google geolocation API for Lat/Long
$address = $_POST['usr_street'].' '.$_POST['usr_city'].' '.$_POST['usr_state'].', '.$_POST['usr_zip'];
// Get JSON results from this request
$geo = file_get_contents('https://maps.googleapis.com/maps/api/geocode/json?address='.urlencode($address).'&sensor=false&key='.APIKEY);
// Convert JSON
$geo = json_decode($geo, true);
if ($geo['status'] == 'OK') {
// Get Lat & Long
$latitude = $geo['results'][0]['geometry']['location']['lat'];
$longitude = $geo['results'][0]['geometry']['location']['lng'];
}else{
$latitude = NULL;
$longitude = NULL;
}
From here, I can push $latitude and $longitude into my DB array and save the value in my DB column. Check it.
EX.
$userData = array(
'usr_first_name' => $_POST['usr_first_name'],
'usr_last_name' => $_POST['usr_last_name'],
'usr_password' => password_hash($_POST['usr_password'], PASSWORD_DEFAULT),
'usr_email' => $_POST['usr_email'],
'usr_company_name' => $_POST['usr_company_name'],
'usr_website' => $_POST['usr_website'],
'usr_street' => $_POST['usr_street'],
'usr_city' => $_POST['usr_city'],
'usr_state' => $_POST['usr_state'],
'usr_zip' => $_POST['usr_zip'],
'usr_phone1' => $_POST['usr_phone1'],
'usr_lat' => $latitude,
'usr_long' => $longitude,
//->etc...etc...etc...
);
//->$user is user object declared further up in document and comes from external user class -> user.class.php
//-> insert is function from external USER class that inserts query into DB.
$insert = $user->insert($userData);
Hope this helps others that are struggling with Google Maps API geo Location with PHP. In terms of dynamically collecting Lat and Long using simple address string constructed from form entries.
Related
Up until yesterday I had a perfectly working budget organizer site/app working with iGoogle.
Through PHP, using the following little line
file_get_contents('http://www.google.com/ig/calculator?hl=en&q=1usd=?eur');
and similar I was able to get all I needed.
As of today, this is no longer working. When I looked into the issue, what has happened is that Google has retired iGoogle. Bummer!
Anyway, I was looking around elsewhere but I can't find anything that fits my needs. I would REALLY love to just fix it and get it running again by just switching this one line of code (i.e. changing the Google address with the address of some other currency API available) but it seems like none does.
The API from rate-exchange.appspot.com seems like it could be a iGoogle analog but, alas, it never works. I keep getting an "Over Quota" message.
(Here comes an initial question: anybody out there know of a simple, reliable, iGoogle-sort API?)
So I guess the natural thing would be to the Yahoo YQL feature (at least I suppose it is as reliable).
Yahoo's queries look like this:
http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.xchange where pair in ("USDEUR", "USDJPY", "USDBGN")&env=store://datatables.org/alltableswithkeys
What I really can't figure out is how to parse this data. It outputs an XML.
What I used to have is this:
function exchange($inputAmount,$inputCurrency,$outputCurrency) {
$exchange = file_get_contents('http://www.google.com/ig/calculator?hl=en&q='.$inputAmount.$inputCurrency.'=?'.$outputCurrency);
$exchange = explode('"', $exchange);
$exchange = explode('.', $exchange['3']);
$exchange[0] = str_replace(" ", "",preg_replace('/\D/', '', $exchange[0]));
if(isset($exchange[1])){
$exchange[1] = str_replace(" ", "",preg_replace('/\D/', '', $exchange[1]));
$exchange = $exchange[0].".".$exchange[1];
} else{
$exchange = $exchange[0];
}
return $exchange;
}
So the user was able to get the exchange rate from an input currency such as "USD" and an output currency such as "EUR" on a specific amount of money. As I said, this was working swimmingly up until yesterday night.
Any ideas?
Never mind! Solved it!
For anyone interested, here's what I did to get my code to work (with the least chnges possible) with the Yahoo YQL:
// ** GET EXCHANGE INFO FROM YAHOO YQL ** //
$url = 'http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.xchange where pair in ("USDEUR", "EURUSD")&env=store://datatables.org/alltableswithkeys'; //<-- Get the YQL info from Yahoo (here I'm only interested in converting from USD to EUR and vice-versa; you should add all conversion pairs you need).
$xml = simplexml_load_file($url) or die("Exchange feed not loading!"); //<-- Load the XML file into PHP variable.
$exchange = array(); //<-- Build an array to hold the data we need.
for($i=0; $i<2; $i++): //<-- For loop to get data specific to each exchange pair (you should change 2 to the actual amount of pairs you're querying for).
$name = (string)$xml->results->rate[$i]->Name; //<-- Get the name of the pair and turn it into a string (this looks like this: "USD to EUR").
$rate = (string)$xml->results->rate[$i]->Rate; //<-- Do the same for the actual rate resulting from the conversion.
$exchange[$name] = $rate; //<-- Put the data pairs into the array.
endfor; //<-- End for loop. :)
// ** WORK WITH EXCHANGE INFO ** //
$toeur = array( //<-- Create new array specific for conversion to one of the units needed.
'usd' => $exchange['USD to EUR'], //<-- Create an array key for each unit used. In this case, in order to get the conversion of USD to EUR I ask for it from my $exchange array with the pair Name.
'eur' => 1); //<-- The way I coded the app, I found it more practical to also create a conversion for the unit into itself and simply use a 1, which translates into "do not convert"
$tousd = array(
'eur' => $exchange['EUR to USD'],
'usd' => 1);
This is basically all you need to get all the exchange info you want. After that, you use it all something like this:
amount*$toxxx['coin'];
So, say I wanted to know how many Euro is 100 USD right now:
100*$toeur['usd'];
Piece of cake!
Still a very useful solution by QuestionerNo27. Since early 2015, however, Yahoo YQL apparently slightly changed the XML output of their api. 'Name' now no longer translates into a string like 'USD to EUR', but to 'USD/EUR' and should in the code above be referenced this way:
$toeur = array(
'usd' => $exchange['USD/EUR']
instead of
$toeur = array(
'usd' => $exchange['USD to EUR']
and in a similar fashion for other currency conversions.
I created a routine to convert the currency based on #QuestionerNo27 http://jamhubsoftware.com/geoip/currencyconvertor.php?fromcur=USD&tocur=EUR&amount=1 you can consume this
<?php
$fromcur = $_GET['fromcur'];
$tocur = $_GET['tocur'];
$amt = $_GET['amount'];
// ** GET EXCHANGE INFO FROM YAHOO YQL ** //
$url = 'http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.xchange where pair in ("'.$fromcur.$tocur.'")&env=store://datatables.org/alltableswithkeys'; //<-- Get the YQL info from Yahoo (here I'm only interested in converting from USD to EUR and vice-versa; you should add all conversion pairs you need).
$xml = simplexml_load_file($url) or die("Exchange feed not loading!"); //<-- Load the XML file into PHP variable.
$exchange = array(); //<-- Build an array to hold the data we need.
for($i=0; $i<2; $i++): //<-- For loop to get data specific to each exchange pair (you should change 2 to the actual amount of pairs you're querying for).
$name = (string)$xml->results->rate[$i]->Name; //<-- Get the name of the pair and turn it into a string (this looks like this: "USD to EUR").
$rate = (string)$xml->results->rate[$i]->Rate; //<-- Do the same for the actual rate resulting from the conversion.
$exchange[$name] = $rate; //<-- Put the data pairs into the array.
endfor; //<-- End for loop. :)
// ** WORK WITH EXCHANGE INFO ** //
$conv = $fromcur . '/' . $tocur;
$toeur = array( //<-- Create new array specific for conversion to one of the units needed.
$tocur => $amt*$exchange[$conv], //<-- Create an array key for each unit used. In this case, in order to get the conversion of USD to EUR I ask for it from my $exchange array with the pair Name.
$fromcur => $amt,
"ex_amt" =>$amt*$exchange[$conv]); //<-- The way I coded the app, I found it more practical to also create a conversion for the unit into itself and simply use a 1, which translates into "do not convert"
echo json_encode($toeur);
?>
I am using a PHP script (this one) to generate a JSON file for a Google Map.
this is the PHP code (note: I am using Laravel):
<?php
$query = "SELECT id, info, lat, lng FROM places";
$results = DB::select($query);
$myLocations = array();
$i = 0;
$testLoc = array('loc95' => array( 'lat' => 15, 'lng' => 144.9634 ));
foreach ($results as $result)
{
$myLocation = array(
'loc'.++$i => array(
'lat' => round((float)$result->lat, 4),
'lng' => round((float)$result->lng, 4)
));
$myLocations += $myLocation;
}
$myLocations += $testLoc;
echo json_encode($myLocations);
?>
and this is the output:
{"loc1":{"lat":45.4833,"lng":9.1854},"loc2":{"lat":45.4867,"lng":9.1648},"loc3":{"lat":45.4239,"lng":9.1652},"loc95":{"lat":15,"lng":144.9634}}
ok. the script I use to put the JSON data in a Google Map, unfortunately, keeps ignoring any data coming from the MySQL database, and shows only the test data place(s). I have tried to swap data, to put in test data the same info found in database... nothing, I keep seeing only the test data.
but, really: I cannot figure out why. What am I missing... ?
You wrote that you're using another script and that the other script only shows the testlocations on google maps.
My guess is that you didn't update the other script to your needs, specifically my crystal ball is telling me that you still have this line in there:
setMarkers(locs);//Create markers from the initial dataset served with the document.
In your question you only showed the part which worked and I agree, but you only mentioned that "something else" isn't working. If you want an answer for that part, try reprashing your question and include the parts which cause you problems.
I'm currently running into a massive wall due to a problem i cannot seem to solve.
The problem is that, when you issue a payment through the Facebook payment platform (facebook javascript sdk), it sends data to your callback page, which should handle the payment on the background.
This all works decent, but there is 1 problem: The order ID that facebook uses is a 64bit ID, and my server is a 32bits server, thus it loses precision on the ID when it gets saved to a variable in the callback page. This ultimately results in not being able to get a proper order_ID in the end, because it cannot save the ID.
The issue has been described on several pages on this forum, for example:
facebook credit callback, order_id changes format changes after moving to a new server
and
PHP: Converting a 64bit integer to string
Yet, on both pages there is no solution to the problem, and i cannot seem to fix this myself.
I have tried to convert the json data that facebook sends to my callback page into string data instead of an array with integers (this happens in the basic code provided by facebook), but i just cannot get this to work.
Seeing that others have overcome this problem (without having to migrate everything to a 64bits server), i am wondering how.
Is anyone able to shine a light on this subject?
Edit:
I have tried converting to string, the standard facebook code that gets called to decode the json data (code provided by facebook):
$request = parse_signed_request($_POST['signed_request'], $app_secret);
This calls the function parse_signed_request, which does:
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
This function decodes the encrypted json data from facebook (using the app secret) and should decode the json data to a PHP array.
That function uses the following function (the exact:
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
Now, the above code results in the order ID not being saved properly, and it loses its precision, resulting in an id like: 4.8567130814993E+14
I have tried to use the following function to somehow decode the json data into a string (so the 64bit integer ID does not lose its precision), but to no avail:
function largeint($rawjson) {
$rawjson = substr($rawjson, 1, -1);
$rawjson = explode(',' , $rawjson);
array_walk($rawjson, 'strfun');
$rawjson = implode(',', $rawjson);
$rawjson = '{' . $rawjson . '}';
$json = json_decode($rawjson);
return $json;
}
function strfun(&$entry, $key) {
$data = explode(':', $entry);
if (FALSE === strpos($data[1], '"')) {
$data[1] = '"' . $data[1] . '"';
$entry = implode(':', $data);
}
}
Edit (Eugenes answer):
If i were to try modifying the JSON data before i use json_decode to make it a php variable, i should be using the preg_replace function?
Below is an example of the initial JSON data that gets sent to the callback page to initiate the payment process.
Here you can already see what the problem is (this is after using json_decode, the id and other data lose their precision). The ID's are modified to not reflect any real data.
If you compare the buyer ID on the top and user id on the bottom, you can see precision is lost.
Array
(
[algorithm] => HMAC-SHA256
[credits] => Array
(
[buyer] => 1.0055555551318E+14
[receiver] => 1.0055555551318E+14
[order_id] => 5.2555555501665E+14
[order_info] => {"item_id":"77"}
[test_mode] => 1
)
[expires] => 1358456400
[issued_at] => 1358452270
[oauth_token] => AAAH4s2ZCCEMkBAPiGSNsmj98HNdTandalotmoredata
[user] => Array
(
[country] => nl
[locale] => nl_NL
[age] => Array
(
[min] => 21
)
)
[user_id] => 100555555513181
)
Edit #3:
I have tried the following to make all the integers in the JSON data seen as strings, but that results in an error from the facebook platform. It does however change the integers to a string, so i do not lose precision (too bad nothing else works now xD)
preg_replace('/([^\\\])":([0-9]{10,})(,|})/', '$1":"$2"$3', $a)
Which version of PHP are you running?
If you are running a version of PHP that supports the JSON "JSON_BIGINT_AS_STRING" option, that may be your answer. You may have to modify their library wherever json_decode is being used to add that option. See http://php.net/manual/en/function.json-decode.php
If your PHP version does not support JSON_BIGINT_AS_STRING, then your options are limited to:
The hacky option: Do some kind of regex operation on the JSON string as it comes back from the FB API and wrap that big ints in double-quotes, so that they decode as a string and not a big int.
The ideal option: Bite the bullet and migrate to a 64 bit environment. It will save you from a lot of headaches in the long run.
I'm sending a string to a php script and trying to make a jsonarray out of it for processing and putting it into an sql table. I send a string from an android application to the server:
[{"name":"bob","datetime":"2012-04-14 10:40"},{"name":"Anonymous","datetime":"2012-04-14 10:40"}]
I used http://jsonlint.com/ to validate the jsonarray and it is valid. When I have the following php script:
<?php
$json_as = stripslashes($_POST["json_a"]);
//$out.=json_decode(jsoninfo);
$realjson = json_decode($json_as, true);
//print $json_as;
//echo $realjson[name];
//print $realjson[name];
print $json_as;
?>
I see get the following info in my LogCat:
The Response text is [{"name":"bob","datetime":"2012-04-14 10:40"},{"name":"Anonymous","datetime":"2012-04-14 10:40"}]
I've been trying to use this for reference without luck: http://webhole.net/2009/08/31/how-to-read-json-data-with-php/
But when I try to change the php script to pring something out from the variable $realjson, nothing comes back. How do I get the information out of the json string I am sending?
Here is complete tutorial to send and recieve JSON data between PHP and Android.
I hope this can help you.
Query:
http://localhost/testJson.php?data=[{%22name%22:%22bob%22,%22datetime%22:%222012--04-14%2010:40%22},{%22name%22:%22Anonymous%22,%22datetime%22:%222012-04-14%2010:40%22}]
PHP CODE :
COde :
<?php
$data = $_REQUEST['data'];
print_r(json_decode($data));
?>
Result :
Array ( [0] => stdClass Object ( [name] => bob [datetime] =>
2012--04-14 10:40 ) 1 => stdClass Object ( [name] => Anonymous
[datetime] => 2012-04-14 10:40 ) )
Sent a string in JSON format, then used the following code:
$json_as = stripslashes($_POST["json_a"]);
trim($json_as, "[");
trim($json_as, "]");
$realjson = json_decode($json_as, true);
//$uses = "name";
mysql_select_db("thoughtsdata",$con);
foreach($realjson as $item) {
$name = $item[name];
$datetime = $item[datetime];
//processed code
}
I am trying to build a restful web service for my website. I have a php mysql query using the following code:
function mysql_fetch_rowsarr($result, $taskId, $num, $count){
$got = array();
if(mysql_num_rows($result) == 0)
return $got;
mysql_data_seek($result, 0);
while ($row = mysql_fetch_assoc($result)) {
$got[]=$row;
}
print_r($row)
print_r(json_encode($result));
return $got;
which returns the following using the print_r($data) in the code above
Array ( [0] => Array ( [show] => Blip TV Photoshop Users TV [region] => UK [url] => http://blip.tv/photoshop-user-tv/rss [resourceType] => RSS / Atom feed [plugin] => Blip TV ) [1] => Array ( [show] => TV Highlights [region] => UK [url] => http://feeds.bbc.co.uk/iplayer/highlights/tv [resourceType] => RSS / Atom feed [plugin] => iPlayer (UK) ) )
Here is the json it returns:
[{"show":"Blip TV Photoshop Users TV","region":"UK","url":"http:\/\/blip.tv\/photoshop-user-tv\/rss","resourceType":"RSS \/ Atom feed","plugin":"Blip TV"},{"show":"TV Highlights","region":"UK","url":"http:\/\/feeds.bbc.co.uk\/iplayer\/highlights\/tv","resourceType":"RSS \/ Atom feed","plugin":"iPlayer (UK)"}]
I am using the following code to add some items to the array then convert it to json and return the json.
$got=array(array("resource"=>$taskId,"requestedSize"=>$num,"totalSize"=>$count,"items"),$got);
using the following code to convert it to json and return it.
$response->body = json_encode($result);
return $response;
this gives me the following json.
[{"resource":"video","requestedSize":2,"totalSize":61,"0":"items"},[{"show":"Blip TV Photoshop Users TV","region":"UK","url":"http:\/\/blip.tv\/photoshop-user-tv\/rss","resourceType":"RSS \/ Atom feed","plugin":"Blip TV"},{"show":"TV Highlights","region":"UK","url":"http:\/\/feeds.bbc.co.uk\/iplayer\/highlights\/tv","resourceType":"RSS \/ Atom feed","plugin":"iPlayer (UK)"}]]
The consumers of the API want the json in the following format and I cannot figure out how to get it to come out this way. I have searched and tried everything I can find and still not get it. And I have not even started trying to get the xml formatting
{"resource":"video", "returnedSize":2, "totalSize":60,"items":[{"show":"Blip TV Photoshop Users TV","region":"UK","url":"http://blip.tv/photoshop-user-tv/rss","resourceType":"RSS / Atom feed","plugin":"Blip TV"},{"show":"TV Highlights","region":"UK", "url":"http://feeds.bbc.co.uk/iplayer/highlights/tv","resourceType":"RSS / Atom feed","plugin":"iPlayer (UK)"}]}
I appreciate any and all help with this. I have setup a copy of the database with readonly access and can give all the source code it that will help, I will warn you that I am just now learning php, I learned to program in basic, fortran 77 so the php is pretty messy and I would guess pretty bloated.
OK The above about json encoding was answered. The API consumers also want the special character "/", not to be escaped since it is a URL. I tried the "JSON_UNESCAPED_SLASHES " in the json_encode and got the following error.
json_encode() expects parameter 2 to be long
Your $result line should look like
$result=array(
"resource"=>$taskId,
"requestedSize"=>$num,
"totalSize"=>$count,
"items" => $got
);