He escrito una clase basada en la respuesta "Chandra Nakka". Con suerte, puede ayudar a las personas a guardar la información del geoplugin en una sesión para que la carga sea mucho más rápida al recuperar la información. También guarda los valores en una matriz privada, por lo que recuperarlos en el mismo código es lo más rápido posible.
class Geo {
private $_ip = null;
private $_useSession = true;
private $_sessionNameData = 'GEO_SESSION_DATA';
private $_hasError = false;
private $_geoData = [];
const PURPOSE_SUPPORT = [
"all", "*", "location",
"request",
"latitude",
"longitude",
"accuracy",
"timezonde",
"currencycode",
"currencysymbol",
"currencysymbolutf8",
"country",
"countrycode",
"state", "region",
"city",
"address",
"continent",
"continentcode"
];
const CONTINENTS = [
"AF" => "Africa",
"AN" => "Antarctica",
"AS" => "Asia",
"EU" => "Europe",
"OC" => "Australia (Oceania)",
"NA" => "North America",
"SA" => "South America"
];
function __construct($ip = null, $deepDetect = true, $useSession = true)
{
// define the session useage within this class
$this->_useSession = $useSession;
$this->_startSession();
// define a ip as far as possible
$this->_ip = $this->_defineIP($ip, $deepDetect);
// check if the ip was set
if (!$this->_ip) {
$this->_hasError = true;
return $this;
}
// define the geoData
$this->_geoData = $this->_fetchGeoData();
return $this;
}
function get($purpose)
{
// making sure its lowercase
$purpose = strtolower($purpose);
// makeing sure there are no error and the geodata is not empty
if ($this->_hasError || !count($this->_geoData) && !in_array($purpose, self::PURPOSE_SUPPORT)) {
return 'error';
}
if (in_array($purpose, ['*', 'all', 'location'])) {
return $this->_geoData;
}
if ($purpose === 'state') $purpose = 'region';
return (isset($this->_geoData[$purpose]) ? $this->_geoData[$purpose] : 'missing: '.$purpose);
}
private function _fetchGeoData()
{
// check if geo data was set before
if (count($this->_geoData)) {
return $this->_geoData;
}
// check possible session
if ($this->_useSession && ($sessionData = $this->_getSession($this->_sessionNameData))) {
return $sessionData;
}
// making sure we have a valid ip
if (!$this->_ip || $this->_ip === '127.0.0.1') {
return [];
}
// fetch the information from geoplusing
$ipdata = @json_decode($this->curl("http://www.geoplugin.net/json.gp?ip=" . $this->_ip));
// check if the data was fetched
if (!@strlen(trim($ipdata->geoplugin_countryCode)) === 2) {
return [];
}
// make a address array
$address = [$ipdata->geoplugin_countryName];
if (@strlen($ipdata->geoplugin_regionName) >= 1)
$address[] = $ipdata->geoplugin_regionName;
if (@strlen($ipdata->geoplugin_city) >= 1)
$address[] = $ipdata->geoplugin_city;
// makeing sure the continentCode is upper case
$continentCode = strtoupper(@$ipdata->geoplugin_continentCode);
$geoData = [
'request' => @$ipdata->geoplugin_request,
'latitude' => @$ipdata->geoplugin_latitude,
'longitude' => @$ipdata->geoplugin_longitude,
'accuracy' => @$ipdata->geoplugin_locationAccuracyRadius,
'timezonde' => @$ipdata->geoplugin_timezone,
'currencycode' => @$ipdata->geoplugin_currencyCode,
'currencysymbol' => @$ipdata->geoplugin_currencySymbol,
'currencysymbolutf8' => @$ipdata->geoplugin_currencySymbol_UTF8,
'city' => @$ipdata->geoplugin_city,
'region' => @$ipdata->geoplugin_regionName,
'country' => @$ipdata->geoplugin_countryName,
'countrycode' => @$ipdata->geoplugin_countryCode,
'continent' => self::CONTINENTS[$continentCode],
'continentcode' => $continentCode,
'address' => implode(", ", array_reverse($address))
];
if ($this->_useSession) {
$this->_setSession($this->_sessionNameData, $geoData);
}
return $geoData;
}
private function _startSession()
{
// only start a new session when the status is 'none' and the class
// requires a session
if ($this->_useSession && session_status() === PHP_SESSION_NONE) {
session_start();
}
}
private function _defineIP($ip, $deepDetect)
{
// check if the ip was set before
if ($this->_ip) {
return $this->_ip;
}
// check if the ip given is valid
if (filter_var($ip, FILTER_VALIDATE_IP)) {
return $ip;
}
// try to get the ip from the REMOTE_ADDR
$ip = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP);
// check if we need to end the search for a IP if the REMOTE_ADDR did not
// return a valid and the deepDetect is false
if (!$deepDetect) {
return $ip;
}
// try to get the ip from HTTP_X_FORWARDED_FOR
if (($ip = filter_input(INPUT_SERVER, 'HTTP_X_FORWARDED_FOR', FILTER_VALIDATE_IP))) {
return $ip;
}
// try to get the ip from the HTTP_CLIENT_IP
if (($ip = filter_input(INPUT_SERVER, 'HTTP_CLIENT_IP', FILTER_VALIDATE_IP))) {
return $ip;
}
return $ip;
}
private function _hasSession($key, $filter = FILTER_DEFAULT)
{
return (isset($_SESSION[$key]) ? (bool)filter_var($_SESSION[$key], $filter) : false);
}
private function _getSession($key, $filter = FILTER_DEFAULT)
{
if ($this->_hasSession($key, $filter)) {
$value = filter_var($_SESSION[$key], $filter);
if (@json_decode($value)) {
return json_decode($value, true);
}
return filter_var($_SESSION[$key], $filter);
} else {
return false;
}
}
private function _setSession($key, $value)
{
if (is_array($value)) {
$value = json_encode($value);
}
$_SESSION[$key] = $value;
}
function emptySession($key) {
if (!$this->_hasSession($key)) {
return;
}
$_SESSION[$key] = null;
unset($_SESSION[$key]);
}
function curl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
}
Respondiendo la pregunta 'op' con esta clase puedes llamar
$country = (new \Geo())->get('country'); // United Kingdom
Y las otras propiedades disponibles son:
$geo = new \Geo('185.35.50.4');
var_dump($geo->get('*')); // allias all / location
var_dump($geo->get('country'));
var_dump($geo->get('countrycode'));
var_dump($geo->get('state')); // allias region
var_dump($geo->get('city'));
var_dump($geo->get('address'));
var_dump($geo->get('continent'));
var_dump($geo->get('continentcode'));
var_dump($geo->get('request'));
var_dump($geo->get('latitude'));
var_dump($geo->get('longitude'));
var_dump($geo->get('accuracy'));
var_dump($geo->get('timezonde'));
var_dump($geo->get('currencyCode'));
var_dump($geo->get('currencySymbol'));
var_dump($geo->get('currencySymbolUTF8'));
Volviendo
array(15) {
["request"]=>
string(11) "185.35.50.4"
["latitude"]=>
string(7) "51.4439"
["longitude"]=>
string(7) "-0.1854"
["accuracy"]=>
string(2) "50"
["timezonde"]=>
string(13) "Europe/London"
["currencycode"]=>
string(3) "GBP"
["currencysymbol"]=>
string(2) "£"
["currencysymbolutf8"]=>
string(2) "£"
["city"]=>
string(10) "Wandsworth"
["region"]=>
string(10) "Wandsworth"
["country"]=>
string(14) "United Kingdom"
["countrycode"]=>
string(2) "GB"
["continent"]=>
string(6) "Europe"
["continentcode"]=>
string(2) "EU"
["address"]=>
string(38) "Wandsworth, Wandsworth, United Kingdom"
}
string(14) "United Kingdom"
string(2) "GB"
string(10) "Wandsworth"
string(10) "Wandsworth"
string(38) "Wandsworth, Wandsworth, United Kingdom"
string(6) "Europe"
string(2) "EU"
string(11) "185.35.50.4"
string(7) "51.4439"
string(7) "-0.1854"
string(2) "50"
string(13) "Europe/London"
string(3) "GBP"
string(2) "£"
string(2) "£"