I'm struggling to get the "Adams County" from "administrative_area_level_2" type
from this api response
http://maps.googleapis.com/maps/api/geocode/json?latlng=39.76144296429947,-104.8011589050293&sensor=false .
I simply need to output the county based on the latitude and longitude.
$query = #unserialize(file_get_contents('http://maps.googleapis.com/maps/api/geocode/json?latlng=39.76144296429947,-104.8011589050293&sensor=false'));
echo 'Hello visitor from '.$query["response"];
This is what I have for now. Thank you.
You will need to use a recursive search and keep track of the previous found item in the result array.
$url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng=39.76144296429947,-104.8011589050293&sensor=false';
$query = #json_decode(file_get_contents($url),true);
$address_components = $query['results'][0]['address_components'];
array_walk_recursive( $address_components,
function($item, $key) use(&$prev_item, &$stop){
if($item == 'administrative_area_level_2'){
$stop = true;
}
else {
if(!$stop)
$prev_item = $item;
}
});
var_dump($prev_item);
Use json_decode instead of unserialize, as the response is in JSON format.
Then just iterate the items in a loop or two, for example:
$url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng=39.76144296429947,-104.8011589050293&sensor=false'; $response = json_decode(file_get_contents($url), true);
if (empty($response['results'])) {
// handle error
}
$long_name = null;
foreach ($response['results'] as $r) {
if (empty($r['address_components']) || empty($r['types']))
continue;
if (array_search('administrative_area_level_2', $r['types']) === false)
continue;
foreach ($r['address_components'] as $ac) {
if (array_search('administrative_area_level_2', $ac['types']) !== false) {
$long_name = $ac['long_name'];
break;
}
}
}
echo $long_name;
Output
Adams County
Related
I have this JSON here
At the root, there is a command(property) as wp which has 39 sub-commands(sub-properties) as cache, cap, checksum...etc, where each has its own subcommands and this goes up to 4 levels
The better part is that all subcommands are arranged in ascending order, i.e.; strings are arranged in ascending order.
I want to traverse and search whether a command like wp site create or wp term delete exists in the JSON tree. I don't want to iterate using a for loop due to huge time complexity. It's been too long since I've completed my engineering and if my memory serves correctly, a tree structure would greatly improvise the search time.
Can anyone point me to the right direction on achieving this? I'm using PHP as my language.
here's a binary search solution, you'll need to put your json into a file...
NOTE: because wp isn't in a subcommands array you can't search for it
<?php
function binarySearch(&$myArray, $search, $start, $end)
{
$middle = ($start + $end) >> 1; // divide by 2
if ($middle >= $start) {
if ($search > $myArray[$middle]['name']) { // $search must be in top half of array
$result = binarySearch($myArray, $search, $middle + 1, $end);
} elseif ($search < $myArray[$middle]['name']) { // $search must be in bottom half of array
$result = binarySearch($myArray, $search, $start, $middle - 1);
} else { // $search is here
$result = $middle;
}
} else {
$result = false; // $search not found
}
return $result;
}
function findCommand($arrFound, $strFind)
{
$arrFind = explode(' ', $strFind);
while ($arrFound !== false and list($key, $strCommand) = each($arrFind)) {
$arrSearch = $arrFound['subcommands'];
if (($key = binarySearch($arrSearch, $strCommand, 0, count($arrSearch) - 1)) === false) {
$arrFound = false;
} else {
$arrFound = $arrSearch[$key];
}
}
return $arrFound;
}
// get json from file and convert it to an array
$arrJson = json_decode(file_get_contents('items.json'), true);
$arrCommand = findCommand($arrJson, 'site create');
var_dump($arrCommand);
$arrCommand = findCommand($arrJson, 'term delete');
var_dump($arrCommand);
though using native functions array_search() and array_column() will probably be quicker
<?php
function findCommand($arrFound, $strFind)
{
$arrFind = explode(' ', $strFind);
while ($arrFound !== false and list($key, $strCommand) = each($arrFind)) {
$arrSearch = $arrFound['subcommands'];
if (($key = array_search($strCommand, array_column($arrSearch, 'name'))) === false) {
$arrFound = false;
} else {
$arrFound = $arrSearch[$key];
}
}
return $arrFound;
}
// get json from file and convert it to an array
$arrJson = json_decode(file_get_contents('items.json'), true);
$arrCommand = findCommand($arrJson, 'site create');
var_dump($arrCommand);
$arrCommand = findCommand($arrJson, 'term delete');
var_dump($arrCommand);
I'm pulling data from an XML file using the following code:
<?php
$url = 'http://www.inveroak.com/readerimages/livepanel/91221.xml';
$xml = simplexml_load_file($url);
$items = array();
$exclude = array('4419','4373');
$items = array_diff($items, $exclude);
foreach($xml as $Reader) {
$items[] = $Reader;
}
usort ($items, function($a, $b) {
return strcmp($a->Status,$b->Status);
});
foreach($items as $Reader) {
if($Reader->Status != 'Logged Off' && $Reader->Picture != 'None')
{
include '/extras/reader-single.php';
}
}
?>
The two lines showing $exclude and $items I've added afer seeing another post excluding values from a foreach loop about excluding from XML, but when i load the page.. the two records that have the PINs specified, are still showing.
Is this the correct way to exclude pulling certain records from an XML file?
Any help is greatly appreciated!
EDIT: The four digit numbers entered are a PIN number found at Reader->PIN
After thinking, could it be that it's not making the link between the number and the Reader->PIN on the xml file?
There is a much simpler way to specifically query for attributes - or to exclude them.
$url = 'http://www.inveroak.com/readerimages/livepanel/91221.xml';
$xml = simplexml_load_file($url);
$matches = $xml->xpath( "//Reader[Pin!=4419 and Pin!=4373]" );
This will give you the entire structure, minus the two items # 4419 and # 4373.
As I told in comments, get the pin of each record, compare it to the exclude array, if it is part of the exclude array then just continue the loop. Like this:
$url = 'http://www.inveroak.com/readerimages/livepanel/91221.xml';
$xml = simplexml_load_file($url);
$items = array();
$exclude = array('4419','4373');
$items = array_diff($items, $exclude);
foreach($xml as $Reader) {
$items[] = $Reader;
}
usort ($items, function($a, $b) {
return strcmp($a->Status,$b->Status);
});
foreach($xml as $Reader) {
if($Reader->Status != 'Logged Off'
&& $Reader->Picture != 'None'
// check if the Pin is in exclude array
&& !in_array($Reader->Pin, $exclude)
) {
include '/extras/reader-single.php';
}
}
Alternatively you may use array_filter():
$url = 'http://www.inveroak.com/readerimages/livepanel/91221.xml';
$xml = simplexml_load_file($url);
$items = array();
$exclude = array('4419','4373');
$items = array_diff($items, $exclude);
foreach($xml as $Reader) {
$items[] = $Reader;
}
$items= array_filter($items, function($Reader) use ($exclude) {
if($Reader->Status == 'Logged Off'
|| $Reader->Picture == 'None'
|| in_array($Reader->Pin, $exclude)
) {
return false;
}
return true;
});
usort ($items, function($a, $b) {
return strcmp($a->Status,$b->Status);
});
foreach($items as $Reader) {
include '/extras/reader-single.php';
}
Another way would be filter them out in the first foreach loop:
foreach($xml as $Reader) {
if (array_search($Reader->Pin, $exclude) === FALSE) {
$items[] = $Reader;
}
}
In either case, you do not need:
$items = array_diff($items, $exclude);
array_diff() returns the values from the first array ($items) that do not exist in the second array ($exclude). Because in your case the first array is an empty array, it has no values, so array_diff() will also always return an empty array.
Perhaps someone will come along with an XPath solution - that would be another approach. (EDIT - Ah, I see #pp19dd has supplied this.)
I have a simple data format that goes as follows:
stuff/stuff/stuff
An example would be:
data/test/hello/hello2
In order to retrieve a certain piece of data, one would use my parser, which tries to do the following:
In data/test/hello/hello2
You want to retrieve the data under data/test (which is hello). My parser's code is below:
function getData($data, $pattern)
{
$info = false;
$dataLineArray = explode("\n", $data);
foreach($dataLineArray as &$line)
{
if (strpos($line,$pattern) !== false) {
$lineArray = explode("/", $line);
$patternArray = explode("/", $pattern);
$iteration = 0;
foreach($lineArray as &$lineData)
{
if($patternArray[$iteration] == $lineData)
{
$iteration++;
}
else
{
$info = $lineData;
}
}
}
}
return $info;
}
However, it always seems to return the last item, which in this case is hello2:
echo getData("data/test/hello/hello2", "data/test");
Gives Me;
hello2
What am I doing wrong?
If you want the first element after the pattern, put break in the loop:
foreach($lineArray as $lineData)
{
if($patternArray[$iteration] == $lineData)
{
$iteration++;
}
elseif ($iteration == count($patternArray))
{
$info = $lineData;
break;
}
}
I also check $iteration == count($patternArray) so that it won't return intermediate elements, e.g.
/data/foo/test/hello/hello2
will return hello rather than foo.
P.S. There doesn't seem to be any reason to use references instead of ordinary variables in your loops, since you never assign to the reference variables.
I'm currently working to scrape keyword suggestion from Google. This is the script I'm working with:
<?php
function text_between($start,$end,$string) {
if ($start != '') {$temp = explode($start,$string,2);} else {$temp = array('',$string);}
$temp = explode($end,$temp[1],2);
return $temp[0];
}
function gsscrape($keyword) {
$keyword=str_replace(" ","+",$keyword);
global $kw;
$data=file_get_contents('http://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl=en-US&q='.$keyword);
$data=explode('[',$data,3);
$data=explode('],[',$data[2]);
foreach($data as $temp) {
$kw[]= text_between('"','"',$temp);
}
}
#simple to use, just use yourscriptname.php?keywords
if ($_SERVER['QUERY_STRING']!='') {
gsscrape($_SERVER['QUERY_STRING']);
foreach ($kw as $keyword) {
gsscrape($keyword);
}
//sorted and duplicates removed
sort(array_unique($kw));
#all results echoed with break
foreach ($kw as $keywords) {
echo $keywords. "<br />";
}
}
?>
When accessing directly through the URL Google will give me this response for the keyword money:
["money",["moneygram","money network","money mutual","money trees lyrics","moneyball","moneypak","money","money converter","money order","money2india"]]
However, for some reason when I test it on my website, it's just showing this:
moneygram
moneygram
What needs to be changed so that it displayed each of the keywords like this?
moneygram, money network, money mutual, money trees lyrics, moneyball, moneypak, money, money converter, money order, money2india
This is valid JSON, use json_decode and you are done!
var_dump(json_decode('["money",["moneygram","money network","money mutual","money trees lyrics","moneyball","moneypak","money","money converter","money order","money2india"]]'));
edit - complete example;
<?php
function getKeywordSuggestionsFromGoogle($keyword) {
$keywords = array();
$data = file_get_contents('http://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl=en-US&q='.urlencode($keyword));
if (($data = json_decode($data, true)) !== null) {
$keywords = $data[1];
}
return $keywords;
}
var_dump(getKeywordSuggestionsFromGoogle('money'));
To get the data as an array use this:
function gsscrape($keyword) {
return json_decode(utf8_decode(file_get_contents('http://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl=en-US&q='.urlencode($keyword))),true);
}
Can i parse a plist file with php and kind of get it into an array, like the $_POST[''] so i could call $_POST['body'] and get the string that has the <key> body ?
CFPropertyList - A PHP Implementation Of Apple's plist (PropertyList)
Googling for "php plist parser" turned up this blog post that seems to be able to do what you are asking for.
Took a look at some of the libraries out there but they have external requirements and seem overkill. Here's a function that simply puts the data in to associative arrays. This worked on a couple of exported itunes plist files I tried.
// pass in the full plist file contents
function parse_plist($plist) {
$result = false;
$depth = [];
$key = false;
$lines = explode("\n", $plist);
foreach ($lines as $line) {
$line = trim($line);
if ($line) {
if ($line == '<dict>') {
if ($result) {
if ($key) {
// adding a new dictionary, the line above this one should've had the key
$depth[count($depth) - 1][$key] = [];
$depth[] =& $depth[count($depth) - 1][$key];
$key = false;
} else {
// adding a dictionary to an array
$depth[] = [];
}
} else {
// starting the first dictionary which doesn't have a key
$result = [];
$depth[] =& $result;
}
} else if ($line == '</dict>' || $line == '</array>') {
array_pop($depth);
} else if ($line == '<array>') {
$depth[] = [];
} else if (preg_match('/^\<key\>(.+)\<\/key\>\<.+\>(.+)\<\/.+\>$/', $line, $matches)) {
// <key>Major Version</key><integer>1</integer>
$depth[count($depth) - 1][$matches[1]] = $matches[2];
} else if (preg_match('/^\<key\>(.+)\<\/key\>\<(true|false)\/\>$/', $line, $matches)) {
// <key>Show Content Ratings</key><true/>
$depth[count($depth) - 1][$matches[1]] = ($matches[2] == 'true' ? 1 : 0);
} else if (preg_match('/^\<key\>(.+)\<\/key\>$/', $line, $matches)) {
// <key>1917</key>
$key = $matches[1];
}
}
}
return $result;
}