How do I store areacodes (npa-nxx) in a database for fast lookup?
Here's the deal: I have a variable that contains a phone number and I need to look in a database for the city attached to that phone number.
The problem is, different countries have different formats.
Canada/USA: +19055551234 (+1 > Country, 905 > Area Code, 555 > City Code)
France: +33512345678 (+33 > Country, 5 > Areacode, 1 > City, Other numbers > Subscriber number)
and so on (infos based on wikipedia)
I created a table called 'npanxx' that contain the list of area codes, city code and city attached to each one (with the id of the country and the province/state id):
CountryId, RegionId, PrimaryCity, npa, nxx, fnpanxx
1 11 Acton Vale 450 236 +1450236
I am thinking about the following procedure:
Get all country codes from sql to php array
Go through each entry and check if there's a match from the beginning of the phone number
When (If there's) a match is found
Remove the beginning of the phone number
Get all npa-nxx that belong to that contry and put them in a php array
Go through each value of the array to find a matching beginning
When (If there's) a match is found
Remove the beginning of the phone number
Store data in different variables like: $country = 'Canada'; $city = 'Acton Vale'...
etc, etc.
First mistake (I think): To much database requests (the npanxx table contain 3000 records for only one province in Canada)
Second mistake: I'm pretty sure there's no need to go through each and every npa-nxx code
another problem: It's not sure that if the phone number is a France one that this procedure will work.
And... If there's an entry for, let's say 336 and another for 3364, it might give the wrong result.
Do you have any idea how I can solve this problem ? (I don't ask for any code, I don't want to to do the work for me, I would like some clues though)
This is for a personnel project to make donation for Multiple Sclerosis Society of Canada and would really like to finish that project :)
I would think maybe some kind of set of reg-exes or other pattern matches to whiddle down your options in terms of search. Just some basic way or "guessing" at the possibilities instead of searching all of them.
Here's a small script I wrote in PHP to return the NPA/NXX as a JSON object in real time from area-codes.com.
It returns some very useful data. It's only for the NANP, so it doesn't do so well trying to discern international calls. For that, I would suggest making a table of all international country codes and the appropriate methods to dial them, internationally.
Additionally, network exchange operators demand an international dial code (like 011 for the USA, or + for cell phones, in general) to figure out if the number is international, and then take the steps, above, to figure out where you're trying to go. You could add this constraint into the input field and be done with it.
If you're trying to just get NPA/NXX information in the North American Numbering Plan, though, this script should be very helpful.
Just an aside, the area-codes.com counts online lookups among their free services, and I have found nothing on the site to suggest that this code violates that policy. But this code can be retooled to gather data from other providers, none-the-less.
<?php
// Small script to return and format all data from the NPA/NXX info site www.area-codes.com
// Returns a JSON object.
error_reporting(E_NONE);
$npa = $_GET['npa'];
$nxx = $_GET['nxx'];
function parseInput($input) {
$v = new DOMDocument();
$v->formatOutput = true;
$v->preserveWhiteSpace = false;
$v->loadHTML($input);
$list = $v->getElementsByTagName("td");
$e = false;
$dataOut = array();
$p = "";
foreach($list as $objNode) {
if (!$e) {
$p = $objNode->nodeValue;
$p = strtolower($p);
$p = preg_replace("%[+ .:()\/_-]%", "", $p);
$p = str_replace("\xc2\xa0", "", $p);
$p = trim($p);
}
else {
if ($p != "") {
$d = trim($objNode->nodeValue);
if ($d != "") $dataOut[$p] = $d;
}
$p = "";
}
$e = !$e;
}
return $dataOut;
}
function getNPANXX($npa, $nxx) {
$url = "www.area-codes.com/exchange/exchange.asp?npa=$npa&nxx=$nxx";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_URL, $url);
$response = curl_exec($ch);
curl_close($ch);
$i = strpos($response, "<h3>AreaCode/Prefix $npa-$nxx Details</h3>");
$i = strpos($response, "<table width=\"100%\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\">", $i);
$e = strpos($response, "</table>", $i);
$scan = substr($response, $i, ($e-$i) + 8);
return parseInput($scan);
}
$result = getNPANXX($npa, $nxx);
if (!isset($result['npaareacode'])) {
$result = array("error" => "invalid");
}
echo json_encode($result);
die;
?>
For the query npanxx.php?npa=202&nxx=520 the JSON outputs as follows:
{
"npaareacode":"202",
"nxxusetype":"WIRELESS",
"nxxprefix":"520",
"nxxintroversion":"11\/16\/2007",
"city":"WASHINGTON",
"state":"DC",
"latitude":"38.901",
"county":"DISTRICT OF COLUMBIA",
"longitude":"-77.0315",
"countypopulation":"0",
"lata":"236",
"zipcode":"20005",
"zipcodecount":"0",
"ratecenter":"WSHNGTNZN1",
"zipcodefreq":"0",
"fips":"11001",
"ocn":"6664",
"observesdst":"Unknown",
"cbsacode":"47900",
"timezone":"Eastern (GMT -05:00)",
"cbsaname":"Washington-Arlington-Alexandria, DC-VA-MD-WV",
"carriercompany":"SPRINT SPECTRUM L.P."
}
For your example npanxx.php?npa=450&nxx=236 the data returned is a little bit limited because it's Canada and Canada doesn't provide all the FIPS and carrier data like the United States does, but the returned data still quite useful:
{
"npaareacode":"450",
"nxxusetype":"WIRELESS",
"nxxprefix":"236",
"nxxintroversion":"2002-08-04",
"city":"ACTON VALE",
"state":"QC",
"latitude":"45.6523",
"longitude":"-72.5671",
"countypopulation":"51400",
"lata":"850",
"zipcodecount":"0",
"zipcodefreq":"-1",
"observesdst":"Unknown",
"timezone":"Eastern (GMT -05:00)"
}
Related
I have a script that is responsible for extracting names of people from an external web page by passing an ID as a parameter.
Note: The information provided by this external website is public access, everyone can check this data.
This is the code that I created:
function names($ids)
{
$url = 'https://www.exampledomain.com/es/query_data_example?name=&id='.$ids;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER,array("Accept-Lenguage: es-es,es"));
curl_setopt($ch, CURLOPT_TIMEOUT,10);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$html = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
preg_match_all('/<tr class="odd"><td><a href="(.*?)">/',$html ,$matches);
if (count($matches[1] == 0))
{
$result = "";
}
else if(count($matches[1] == 1))
{
$result = $matches[1][0];
$result = str_replace('/es/person/','', $result);
$result = substr($result, 0,-12);
$result = str_replace('-', ' ', $result);
$result = ucwords($result);
}
return $result;
}
Note2: in the variable $ url I have placed an example url, it is not the real url. It's just an exact example of the original URL that I use in my code.
I make the call to the function, and I show the result with an echo:
$info = names('8476756848');
echo $info;
and everything is perfect, I extracted the name of the person to whom that id belongs.
The problem arises when I try to query that function within a for(or while) loop, since I have an array with many ids
$myids = ["2809475460", "2332318975", "2587100534", "2574144252", "2611639906", "2815870980", "0924497817", "2883119946", "2376743158", "2387362041", "2804754226", "2332833975", "258971534", "2574165252", "2619016306", "2887098054", "2449781007", "2008819946", "2763767158", "2399362041", "2832047546", "2331228975", "2965871534", "2574501252", "2809475460", "2332318975", "2587100534", "2574144252", "2611639906", "2815870980", "0924497817", "2883119946", "2376743158", "2387362041", "2804754226", "2332833975", "258971534", "2574165252", "2619016306", "2887098054", "2449781007", "2008819946", "2763767158", "2399362041", "2832047546", "2331228975", "2965871534", "2574501252", "2809475460", "2332318975", "2587100534", "2574144252", "2611639906", "2815870980", "0924497817", "2883119946", "2376743158", "2387362041", "2804754226", "2332833975", "258971534", "2574165252", "2619016306", "2887098054", "2449781007", "2008819946", "2763767158", "2399362041", "2832047546", "2331228975", "2965871534", "2574501252"];
//Note: These data are for example only, they are not the real ids.
$size = count($myids);
for ($i=0; $i < $size; $i++)
{
//sleep(20);
$data = names($myids[$i]);
echo "ID IS: " . $myids[$i] . "<br> THE NAME IS: " . $data . "<br><br>";
}
The result is something like this:
ID IS: 258971534
THE NAME IS:
ID IS: 2883119946
THE NAME IS:
and so on. I mean, it shows me the Ids but the names do not extract them from the names function.
It shows me the whole list of ids but in the case of the names it does not show me any, as if the function names does not work.
If I put only 3 ids in the array and run the for loop again, then it gives me the names of those 3 ids, because they are few. But when the array contains many ids, then the function already returns no names. It is as if the multiple requests do not accept them or limit them, I do not know.
I have placed the function set_time_limit (0) at the beginning of my php file; to avoid that I get the error of excess time of 30 seconds.
because I thought that was why the function was not working, but it did not work. Also try placing a sleep (20) inside the cycle, before calling the function names to see if it was that it was making many requests very quickly to said web page but it did not work either.
This script is already in production on a server that I have hired and I have this problem that prevents my script from working properly.
Note: There may be arrays with more than 2000 ids or I am even preparing a script that will read files .txt and .csv that will contain more than 10000 ids, which I will extract from each file and call the function name, and then those ids and the names will be saved in a table from a mysql database.
Someone will know why names are not extracted when there are many ids but when they are few for example 1 or 10 the function name does work?
I am trying to integrate First Data e4 Gateway using PHP. I downloaded the VinceG/php-first-data-api PHP First Data Service API class. The code comes with some examples.
I have my Terminal ID (API_LOGIN) and Password (32 character string).
What confuses me is that when I use one of the examples, I don't know how to tell the class that I want to use the demo url, not the production url.
The class comes with two constants:
const LIVE_API_URL = 'https://api.globalgatewaye4.firstdata.com/transaction/';
const TEST_API_URL = 'https://api.demo.globalgatewaye4.firstdata.com/transaction/';
In the First Data console, when I generated my password, it said to use the v12 api, /transaction/v12, so I changed the protected $apiVersion = 'v12';
All I want to do is write my first development transaction using First Data e4. I have yet to get any kind of response. Obviously I need a lot of hand holding to get started.
When I set up a website to use BalancedPayments, they have a support forum that's pretty good, and I was able to get that running fairly quickly. First Data has a lot of documentation, but for some reason not much of it has good PHP examples.
My hope is that some expert has already mastered the VinceG/php-first-data-api, and can help me write one script that works.
Here's the pre-auth code I'm using, that invokes the FirstData class:
// Pre Auth Transaction Type
define("API_LOGIN", "B123456-01");
define("API_KEY", "xxxxxxxxxxyyyyyyyyyyyyzzzzzzzzzz");
$data = array();
$data['type'] = "00";
$data['number'] = "4111111111111111";
$data['name'] = "Cyrus Vance";
$data['exp'] = "0618";
$data['amount'] = "100.00";
$data['zip'] = "33333";
$data['cvv'] = "123";
$data['address'] = "1111 OCEAN BLVD MIAMI FL";
$orderId = "0001";
require_once("FirstData.php");
$firstData = new FirstData(API_LOGIN, API_KEY, true);
// Charge
$firstData->setTransactionType(FirstData::TRAN_PREAUTH);
$firstData->setCreditCardType($data['type'])
->setCreditCardNumber($data['number'])
->setCreditCardName($data['name'])
->setCreditCardExpiration($data['exp'])
->setAmount($data['amount'])
->setReferenceNumber($orderId);
if($data['zip']) {
$firstData->setCreditCardZipCode($data['zip']);
}
if($data['cvv']) {
$firstData->setCreditCardVerification($data['cvv']);
}
if($data['address']) {
$firstData->setCreditCardAddress($data['address']);
}
$firstData->process();
// Check
if($firstData->isError()) {
echo "!!!";
// there was an error
} else {
echo "###";
// transaction passed
}
My number one problem was that I had not created (applied for, with instant approval) a
demo account on First Data. I didn't realize this was a separate thing on First Data. On Balanced Payments, for instance, you have one account, and you can run your script on a test url with test values.
From the Administration panel, click "Terminals", then your Gateway number on the ECOMM row (will look something like AH1234-03), then you have to click "Generate" on password save it to your personal notes), then click UPDATE.
Now replace your parameter values in your test scripts. I use a variable assignment block that looks something like this:
define("API_LOGIN", "AH1234-05"); //fake
define("API_KEY", "44p7797xxx790098z1z2n6f270ys1z0x"); //fake
$data = array();
$data['type'] = "03";
$data['number'] = "4111111111111111";
$data['name'] = "Cyrus Vancce";
$data['exp'] = "0618";
$data['amount'] = "100.00";
$data['zip'] = "33320";
$data['cvv'] = "123";
$data['address'] = "1234 N OCEAN BLVD MIAMI BEACH FL";
$orderId = "0001";
require_once("FirstData.php");
$firstData = new FirstData(API_LOGIN, API_KEY, true);
at the end of the VinceG test scripts, I output my gateway response with a print_r, like this:
$firstData->process();
// Check
if($firstData->isError()) {
echo "!!!";
// there was an error
} else {
echo "###";
// transaction passed
}
echo "<pre>";
print_r($firstData);
I'm trying to audit a vast amount of company data from companycheck.co.uk my current script appears to be looping the first 10 results from only the first page. I had the script gather more than 10 results at one point, but this caused a fatal error after around 600 results (not a timeout error, but a connection error of some sort), I need the script to be more reliable as I'm fetching over 40,000 results.
My code so far:
<?php
set_time_limit(0);
ini_set('max_execution_time', 0);
require 'vendor/autoload.php';
require "Guzzle/guzzle.phar";
// Add this to allow your app to use Guzzle and the Cookie Plugin.
use Guzzle\Http\Client as GuzzleClient;
use Guzzle\Plugin\Cookie\Cookie;
use Guzzle\Plugin\Cookie\CookiePlugin;
use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar;
use Guzzle\Plugin\Cookie\CookieJar\CookieJarInterface;
$Pagesurl = 'http://companycheck.co.uk/search/UpdateSearchCompany?searchTerm=cars&type=name';
$pagesData = json_decode(file_get_contents($Pagesurl), true);
$resultsFound = $pagesData["hits"]["found"];
$pages = ceil($resultsFound / 10);
//echo $pages;
echo "<br>";
for ($p = 0; $p < $pages; $p++) {
$url = 'http://companycheck.co.uk/search/UpdateSearchCompany?searchTerm=cars&type=name&companyPage=' . $p . '';
$data = json_decode(file_get_contents($url), true);
for ($i = 0; $i < 11; $i++) {
$id = $data["hits"]["hit"][$i]["id"];
$TradingAddress = $data["hits"]["hit"][$i]["data"]["address"][0];
$companyName = $data["hits"]["hit"][$i]["data"]["companyname"][0];
$companyNumber = $data["hits"]["hit"][$i]["data"]["companynumber"][0];
$finalURL = "http://companycheck.co.uk/company/" . $id . "";
$httpClient = new GuzzleClient($finalURL);
$httpClient->setSslVerification(FALSE);
$cookieJar = new ArrayCookieJar();
// Create a new cookie plugin
$cookiePlugin = new CookiePlugin($cookieJar);
// Add the cookie plugin to the client
$httpClient->addSubscriber($cookiePlugin);
$httpClient->setUserAgent("Opera/9.23 (Windows NT 5.1; U; en-US)");
$request = $httpClient->get($finalURL);
$response = $request->send();
$body = $response->getBody(true);
$matches = array();
preg_match_all('/<table.*?>(.*?)<\/table>/si', $body, $table);
preg_match('/<meta name=\"keywords\" content=\"(.*?)\"\/>/si', $body, $metaName);
preg_match('/<p itemprop="streetAddress".*?>(.*?)<\/p>/si', $body, $regOffice);
echo "<table><tbody>";
echo "<tr><th>Company Name</th><td>";
echo $companyName;
echo "</td></tr>";
echo "<tr><th>Company Number</th><td>";
echo $companyNumber;
echo "</td></tr>";
echo "<tr><th>Registar Address</th><td>";
echo str_replace("<br>", " ", $regOffice[0]);
echo "</td></tr>
<tr><th>Trading Address</th><td>";
echo $TradingAddress;
echo "</td></tr>
<tr>
<th>Director Name</th>
<td>";
$name = explode(',', $metaName[1]);
echo $name[2];
echo "</td>
</tr></tbody></table>";
echo $table[0][1];
echo "<br><br><br>";
}
}
To get each page, I use http://companycheck.co.uk/search/UpdateSearchCompany?searchTerm=cars&type=name&companyPage=1 which returns json for each page from http://companycheck.co.uk/search/results?SearchCompaniesForm[name]=cars&yt1= and some data, but not all.
With this I can get the ID of each company to navigate to each link and scrape some data from the frontend of the site.
For example the first result is:
"hits":{"found":42842,"start":0,"hit":[{"id":"08958547","data":{"address":["THE ALEXANDER SUITE SILK POINT, QUEENS AVENUE, MACCLESFIELD, SK10 2BB"],"assets":[],"assetsnegative":[],"cashatbank":[],"cashatbanknegative":[],"companyname":["CAR2CARS LIMITED"],"companynumber":["08958547"],"dissolved":["0"],"liabilities":[],"liabilitiesnegative":[],"networth":[],"networthnegative":[],"postcode":["SK10 2BB"],"siccode":[]}}
So the first link is: http://companycheck.co.uk/company/08958547
Then from this I can pull table data such as:
Registered Office
THE ALEXANDER SUITE SILK POINT
QUEENS AVENUE
MACCLESFIELD
SK10 2BB
And information from the meta tags such as:
<meta name="keywords" content="CAR2CARS LIMITED, 08958547,INCWISE COMPANY SECRETARIES LIMITED,MR ROBERT CARTER"/>
An example of one of the results returned:
Company Name CAR2CARS LIMITED
Company Number 08958547
Registar Address
THE ALEXANDER SUITE SILK POINT QUEENS AVENUE MACCLESFIELD SK10 2BB
Trading Address THE ALEXANDER SUITE SILK POINT, QUEENS AVENUE, MACCLESFIELD, SK10 2BB
Director Name INCWISE COMPANY SECRETARIES LIMITED
Telephone No telephone number available.
Email Address No email address available.
Contact Person No contact person available.
Business Activity No Business Activity on record.
Each json page contains 10 company IDs to put into the URL to find the company, from each of these companies I need to scrape data from the full URL, then after these 10 move onto the next page and get the next 10 and loop this up until the last page.
It is almost certainly blocking you deliberately due to an excessive number of requests. Try putting a pause in between requests - that might help you fly under their radar.
The website you are intending to scrape appears to be a private company that is reformatting and republishing data from Companies House, the official record of company information in the UK. This company offers an API which allows 10K requests per month, and this is either free or costs GBP200/month, depending on what data you need. Since you want 40K results immediately, it is no wonder they operate IP blocks.
The rights and wrongs of scraping are complicated, but there is an important point to understand: by copying someone else's data, you are attempting to avoid the costs of collating the data yourself. By taking them from someone else's server, you are also adding to their operational costs without reimbursing them, an economic phenomenon known as an externality.
There are some cases where I am sympathetic to passing on costs in this way, such as where the scrape target is engaged in potential market abuse (e.g. monopolistic practices) and scraping has an alleviating effect. I have heard that some airline companies operate anti-scraping devices because they don't want price scrapers to bring prices down. Since bringing prices down is in the interest of the consumer one could argue that the externality can be justified (on moral, if not legal grounds).
In your case, I would suggest obtaining this data directly from Companies House, where it might be available for a much lower cost. In any case, if you republish valuable data obtained from a scrape, having dodged technical attempts to block you, you may find yourself in legal trouble anyway. If in doubt (and if there is no moral or public interest defence such as I outlined earlier) get in touch with the site operator and ask if what you want to do is OK.
I am trying to get a list of results from Freebase. I have an array of MIDs. Can someone explain how I would structure the query and pass it to the API in PHP?
I'm new to MQL - I can't even seem to get the example to work:
$simplequery = array('id'=>'/topic/en/philip_k_dick', '/film/writer/film'=>array());
$jsonquerystr = json_encode($simplequery);
// The Freebase API requires a query envelope (which allows you to run multiple queries simultaneously) so we need to wrap our original, simplequery structure in two more arrays before we can pass it to the API:
$queryarray = array('q1'=>array('query'=>$simplequery));
$jsonquerystr = json_encode($queryarray);
// To send the JSON formatted MQL query to the Freebase API use cURL:
#run the query
$apiendpoint = "http://api.freebase.com/api/service/mqlread?queries";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$apiendpoint=$jsonquerystr");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$jsonresultstr = curl_exec($ch);
curl_close($ch);
// Decoding the JSON structure back into arrays is performed using json_decode as in:
$resultarray = json_decode($jsonresultstr, true); #true:give us the json struct as an array
// Iterating over the pieces of the resultarray containing films gives us the films Philip K. Dick wrote:
$filmarray = $resultarray["q1"]["result"]["/film/writer/film"];
foreach($filmarray as $film){
print "$film<br>";
}
You're doing everything right. If you weren't, you'd be getting back error messages in your JSON result.
I think what's happened is that the data on Philip K. Dick has been updated to identify him not as the "writer" of films, but as a "film_story_contributor". (He didn't, after all, actually write any of the screenplays.)
Change your simplequery from:
$simplequery = array('id'=>'/topic/en/philip_k_dick', '/film/writer/film'=>array());
To:
$simplequery = array('id'=>'/topic/en/philip_k_dick', '/film/film_story_contributor/film_story_credits'=>array());
You actually can use the Freebase website to drill down into topics to dig up this information, but it's not that easy to find. On the basic Philip K. Dick page (http://www.freebase.com/view/en/philip_k_dick), click the "Edit and Show details" button at the bottom.
The "edit" page (http://www.freebase.com/edit/topic/en/philip_k_dick) shows the Types associated with this topic. The list includes "Film story contributor" but not "writer". Within the Film story contributor block on this page, there's a "detail view" link (http://www.freebase.com/view/en/philip_k_dick/-/film/film_story_contributor/film_story_credits). This is, essentially, what you're trying to replicate with your PHP code.
A similar drill-down on an actual film writer (e.g., Steve Martin), gets you to a property called /film/writer/film (http://www.freebase.com/view/en/steve_martin/-/film/writer/film).
Multiple Queries
You don't say exactly what you're trying to do with an array of MIDs, but firing multiple queries is as simple as adding a q2, q3, etc., all inside the $queryarray. The answers will come back inside the same structure - you can pull them out just like you pull out the q1 data. If you print out your jsonquerystr and jsonresultstr you'll see what's going on.
Modified a bit to include answer into question, as this helped me I've upvoted each, just thought I would provide a more "compleat" answer, as it were:
$simplequery = array('id'=>'/topic/en/philip_k_dick', '/film/film_story_contributor/film_story_credits'=>array());
$jsonquerystr = json_encode($simplequery);
// The Freebase API requires a query envelope (which allows you to run multiple queries simultaneously) so we need to wrap our original, simplequery structure in two more arrays before we can pass it to the API:
$queryarray = array('q1'=>array('query'=>$simplequery));
$jsonquerystr = json_encode($queryarray);
// To send the JSON formatted MQL query to the Freebase API use cURL:
#run the query
$apiendpoint = "http://api.freebase.com/api/service/mqlread?queries";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$apiendpoint=$jsonquerystr");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$jsonresultstr = curl_exec($ch);
curl_close($ch);
// Decoding the JSON structure back into arrays is performed using json_decode as in:
$resultarray = json_decode($jsonresultstr, true); #true:give us the json struct as an associative array
// Iterating over the pieces of the resultarray containing films gives us the films Philip K. Dick wrote:
if($resultarray['code'] == '/api/status/ok'){
$films = $resultarray['q1']['result']['/film/film_story_contributor/film_story_credits'];
foreach ($films as $film){
print "$film</br>";
}
}
is any way (with a rest API will be awesome) to get the Street name corresponding to a Geographical coordinate? I think the name is geocoding, do google have this API? Im PHP developer.
Ex.
<?php
cor="38.115583,13.37579";
echo(geoname(cor)); // this prints: Foro Umberto I - 90133 Palermo
?>
So the output of the function is the street name, the postal code and the city. Thanks for any help and scripts examples!
Yes, just use the "Reverse Geocoding" function in the Google Maps API: http://code.google.com/apis/maps/documentation/geocoding/#ReverseGeocoding
Here's some example code:
$lat="38.115583";
$long = "13.37579";
$url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=$lat,$long&sensor=false";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_ENCODING, "");
$curlData = curl_exec($curl);
curl_close($curl);
$address = json_decode($curlData);
print_r($address);
Here's my PHP function I used for doing a Reverse Geocode lookup for a street address using the Google MAP API. Note, this example gets the output from Google in JSON, but I am doing a simple parse in PHP.
/*
* Use Google Geocoding API to do a reverse address lookup from GPS coordinates
*/
function GetAddress( $lat, $lng )
{
// Construct the Google Geocode API call
//
$URL = "http://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&sensor=false";
// Extract the location lat and lng values
//
$data = file( $URL );
foreach ($data as $line_num => $line)
{
if ( false != strstr( $line, "\"formatted_address\"" ) )
{
$addr = substr( trim( $line ), 22, -2 );
break;
}
}
return $addr;
}
Andrew
Team at OpenGeoCode.Org
btw> Google does have restrictions on using their APIs for commercial purposes. Basically, you need to display the result on a google map.
You could also take a look at using Yahoo!'s PlaceFinder API, which offers reverse geocoding. A minimal example of a call to the API (asking it to return the lightweight data-interchange format du jour, JSON) might look like:
$url = 'http://where.yahooapis.com/geocode?location=55.948496,-3.198909&gflags=R&flags=J';
$response = json_decode(file_get_contents($url));
$location = $response->ResultSet->Results[0];
print_r($location);
Which outputs the first result (hopefully there is one!) which contains properties like street, postal and city.
Another way of using the PlaceFinder API is through Yahoo!'s YQL API, which allows you to make use of SQL-like queries against "data tables" (often, other APIs).
Such a query might look like:
SELECT * FROM geo.placefinder WHERE text="55.948496,-3.198909" AND gflags="R"
(Try this in the YQL console interface)
To make a call to YQL with that query, from PHP, is very similar to the earlier example and should print the same information.
$query = 'SELECT * FROM geo.placefinder WHERE text="55.948496,-3.198909" AND gflags="R"';
$url = 'http://query.yahooapis.com/v1/public/yql?q='.urlencode($query).'&format=json';
$response = json_decode(file_get_contents($url));
$location = $response->query->results->Result;
print_r($location);
As #Elijah mentions, there's a lot of restrictions on the Maps API I gave in my last answer. You're only actually supposed to use it for Google Maps Applications. If that's a problem then you can also try the AdWords API. It also has a similar service but Google charges for it so there's less restriction.