我想通过他们的IP吸引游客…现在我正在使用这个(http://api.hostip.info/country.php?ip=......)

这是我的代码:

<?php

if (isset($_SERVER['HTTP_CLIENT_IP']))
{
    $real_ip_adress = $_SERVER['HTTP_CLIENT_IP'];
}

if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
{
    $real_ip_adress = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
    $real_ip_adress = $_SERVER['REMOTE_ADDR'];
}

$cip = $real_ip_adress;
$iptolocation = 'http://api.hostip.info/country.php?ip=' . $cip;
$creatorlocation = file_get_contents($iptolocation);

?>

好吧,它正常工作,但问题是,这返回国家代码,如US或CA.,而不是整个国家名称,如美国或加拿大。

那么,除了hostip.info提供的这些,还有什么好的选择吗?

我知道我可以编写一些代码,最终将这两个字母转换为整个国家的名称,但我实在懒得编写包含所有国家的代码……

注:出于某种原因,我不想使用任何现成的CSV文件或任何代码,将抓取这个信息为我,像ip2country现成的代码和CSV。


当前回答

用户国家API正是您所需要的。下面是一个使用file_get_contents()的示例代码,就像你最初做的那样:

$result = json_decode(file_get_contents('http://usercountry.com/v1.0/json/'.$cip), true);
$result['country']['name']; // this contains what you need

其他回答

以下是使用guzzle的更清晰的工作版本:

你可以使用curl而不是guzzle,这只是一个简单的get请求。

    function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
        $output = NULL;
        if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
            $ip = $_SERVER["REMOTE_ADDR"];
            if ($deep_detect) {
                if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_CLIENT_IP'];
            }
        }
        $purpose    = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
        $support    = array("country", "countrycode", "state", "region", "city", "location", "address");
        $continents = array(
            "AF" => "Africa",
            "AN" => "Antarctica",
            "AS" => "Asia",
            "EU" => "Europe",
            "OC" => "Australia (Oceania)",
            "NA" => "North America",
            "SA" => "South America"
        );
        if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support, true)) {
            $client = New \GuzzleHttp\Client();
            $ipdat = json_decode($client->request('GET','http://www.geoplugin.net/json.gp',$params = [
                'query' => [
                    'ip' => $ip,
                ]
            ])->getBody()->getContents(),true);
            if (strlen(trim($ipdat['geoplugin_countryCode'])) === 2) {
                switch ($purpose) {
                    case "location":
                        $output = array(
                            "city"           => $ipdat['geoplugin_city'],
                            "state"          => $ipdat['geoplugin_regionName'],
                            "country"        => $ipdat['geoplugin_countryName'],
                            "country_code"   => $ipdat['geoplugin_countryCode'],
                            "continent"      => $continents[strtoupper($ipdat['geoplugin_continentCode'])],
                            "continent_code" => $ipdat['geoplugin_continentCode']
                        );
                        break;
                    case "address":
                        $address = array($ipdat['geoplugin_countryName']);
                        if (@strlen($ipdat['geoplugin_regionName']) >= 1)
                            $address[] = $ipdat['geoplugin_regionName'];
                        if (@strlen($ipdat['geoplugin_city']) >= 1)
                            $address[] = $ipdat['geoplugin_city'];
                        $output = implode(", ", array_reverse($address));
                        break;
                    case "city":
                        $output = $ipdat['geoplugin_city'];
                        break;
                    case "region":
                    case "state":
                        $output = $ipdat['geoplugin_regionName'];
                        break;
                    case "country":
                        $output = $ipdat['geoplugin_countryName'];
                        break;
                    case "countrycode":
                        $output = $ipdat['geoplugin_countryCode'];
                        break;
                }
            }
        }
        return $output;
    }

尝试这个简单的一行代码,您将从他们的ip远程地址获得访客的国家和城市。

$tags = get_meta_tags('http://www.geobytes.com/IpLocator.htm?GetLocation&template=php3.txt&IpAddress=' . $_SERVER['REMOTE_ADDR']);
echo $tags['country'];
echo $tags['city'];

实际上,您可以调用http://api.hostip.info/?ip=123.125.114.144来获取以XML形式显示的信息。

一个带有IP地址到国家API的一行程序

echo file_get_contents('https://ipapi.co/8.8.8.8/country_name/');

> United States

例子:

https://ipapi.co/country_name/ -你的国家

https://ipapi.co/8.8.8.8/country_name/ - IP 8.8.8.8的国家

我根据“Chandra Nakka”的答案写了一个类。希望它能帮助人们,它将信息从geoplugin保存到会话中,以便在调用信息时加载得更快。它还将值保存到一个私有数组中,因此在相同的代码中调用是最快的。

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;
}
}

用这个你可以调用的类来回答“op”问题

$country = (new \Geo())->get('country'); // United Kingdom

其他可用的属性是:

$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'));

返回

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) "£"