Introduction
I have written following PHP code to find location based on IP address. But this code works properly at client side and does not work on server. What may be the problem?
Code
echo $ip = $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("http://ipinfo.io/{$ip}/json"));
echo "<br>".$details->country;
echo "<br>".$details->region;
echo "<br>".$details->city;
echo "<br>".$details->loc;
echo "<br>".$details->postal;
echo "<br>".$details->org;
Problem
This code only shows ip address (executed first line only) and not showing any other details of location.
Not seeing your error message, I'm going to go ahead and assume file_get_contents has been blocked.
CURL the url, much more reliable.
<?php
echo $ip = $_SERVER['REMOTE_ADDR'];
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => "http://ipinfo.io/{$ip}/json"
));
$details = json_decode(curl_exec($curl));
curl_close($curl);
echo "<br>".$details->ip;
echo "<br>".$details->country;
echo "<br>".$details->region;
echo "<br>".$details->city;
echo "<br>".$details->loc;
echo "<br>".$details->postal;
echo "<br>".$details->org;
Your server's IP address can be found as follows:
echo $_SERVER['SERVER_ADDR'];
$_SERVER['REMOTE_ADDR']; gives you client or requesting browser/machine's IP address.
Related
-- Please scroll down to where I marked the PHP --
To explain in better detail.
I made a Leaflet map and in that map I want to load my own location.
Here's my code for that in Javascript, but this is out of question like #Pocketsand and I already discussed. So then scroll down to the PHP code and see if you can get the IP address through the browser.
$part_content = "<div id=\"mapid\"></div>";
//.setView([".$longitude.", ".$latitude."], ".$zoom_factor.");
$part_content .= "<script>
var map = L.map('mapid').fitWorld();
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: 'mapbox.streets'
}).addTo(map);
function onLocationFound(e) {
var radius = e.accuracy / 2;
L.marker(e.latlng).addTo(map)
.bindPopup(\"You are within \" + radius + \" meters from this point\").openPopup();
L.circle(e.latlng, radius).addTo(map);
}
function onLocationError(e) {
alert(e.message);
}
map.on('locationfound', onLocationFound);
map.on('locationerror', onLocationError);
map.locate({setView: true, maxZoom: 16});
</script>";
It's the same code as in this maps source code.
When I go to Firefox, it partly works and on someone else's computer it works fine, when on my computer I get the error from the image I showed you.
So I can't locate on my computer to my own location, as in google maps it works perfectly and my extensions also don't seem to block that part.
PHP:
Basically this:
$ip = !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
Gives me a random IP, because of HTTP_X_FORWARDED_FOR and REMOTE_ADDR gives me the correct IP, but not when I use this from a different IP address then the local one... thats why I check if the proxy is not empty.
This is the full php code for the tracker:
$ip = !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
$url = "http://freegeoip.net/json/$ip";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
$data = curl_exec($ch);
curl_close($ch);
if ($data) {
$location = json_decode($data);
$longitude = $location->longitude;
$latitude = $location->latitude;
$longitude = str_replace(",", ".", $longitude);
$latitude = str_replace(",", ".", $latitude);
}
My current problem is:
$ip = $_SERVER['HTTP_CLIENT_IP'] ? $_SERVER['HTTP_CLIENT_IP'] : ($_SERVER['HTTP_X_FORWARDED_FOR'] ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);
Which gets the correct IP address, but it almost seems like it gets the IP hosts location. Which is not my intention, I intend to get the clients location through the IP address, which currently isn't working.
I tried and tried, but couldn't seem to figure this out and hope you guys know more about this.
Thanks in advance!
I am guessing you didn't visit the URL in the error message? It's a Chrome security thing, try running off a local webserver or getting a https certificate on your remote server.
The Chrome Security team and I propose that, for new and particularly
powerful web platform features, browser vendors tend to prefer to make
the the feature available only to secure origins by default.
[...]
Definitions:
“Secure origins” are origins that match at least one of the following
(scheme, host, port) patterns:
(https, *, *)
(wss, *, *)
(*, localhost, ) (, 127/8, *)
(*, ::1/128, *)
(file, *, —)
(chrome-extension, *, —)
This list may be incomplete, and may need to be changed.
Source: https://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features
To get a client public ip address, in PHP 5.3 or greater use:
<?php
$ip = getenv('HTTP_CLIENT_IP')?:
getenv('HTTP_X_FORWARDED_FOR')?:
getenv('HTTP_X_FORWARDED')?:
getenv('HTTP_FORWARDED_FOR')?:
getenv('HTTP_FORWARDED')?:
getenv('REMOTE_ADDR');
?>
And if that is not working, use an external provider like https://geolocation-db.com
A JSON-P callback example:
<?php
$jsonp = file_get_contents('https://geolocation-db.com/jsonp');
$data = jsonp_decode($jsonp);
print $data->IPv4 . '<br>';
print $data->country_code . '<br>';
print $data->country_name . '<br>';
print $data->state . '<br>';
print $data->city . '<br>';
print $data->postal . '<br>';
print $data->latitude . '<br>';
print $data->longitude . '<br>';
// Strip callback function name and parenthesis
function jsonp_decode($jsonp) {
if($jsonp[0] !== '[' && $jsonp[0] !== '{') {
$jsonp = substr($jsonp, strpos($jsonp, '('));
}
return json_decode(trim($jsonp,'();'));
}
?>
And a JSON example:
<?php
$json = file_get_contents('https://geolocation-db.com/json');
$data = json_decode($json);
print $data->country_code . '<br>';
print $data->country_name . '<br>';
print $data->state . '<br>';
print $data->city . '<br>';
print $data->postal . '<br>';
print $data->latitude . '<br>';
print $data->longitude . '<br>';
print $data->IPv4 . '<br>';
?>
Instead of going with a PHP function I did a leaflet function instead, which tracks the user through the browser.
Using the library: leaflet.locate
Where then I could use the:
// create control and add to map
var lc = L.control.locate().addTo(map);
// request location update and set location
lc.start();
But this isn't the answer to the PHP part of my code, even though this leaflet function also works for now.
Sadly the PHP part can't find the exact address through the IP if the server is at another place, but the leaflet way of doing it through the browser does work. Hope you guys find use in these answers.
I'm trying to access a web service using PHP and SOAP (NuSoap library to be exact) but keep hitting the following error:
HTTP Error: Couldn't open socket connection to server http://rsvpdb01/CRMWebService prior to connect(). This is often a problem looking up the host name.
When accessing this service locally it was necessary to amend my hosts file to redirect the IP address to the 'rsvpdb01' location, however I'm not sure how to do the same on the web server (or if that will actually solve the problem).
The basics of my script are:
<?php
// Pull in the NuSOAP code
require_once('nusoap/lib/nusoap.php');
ini_set('soap.wsdl_cache_enabled',0);
ini_set('soap.wsdl_cache_ttl',0);
// Create the client instance
$action_authenticate = array('Action'=> 'http://tempuri.org/ICRMWebServiceAPI/AuthenticateUser');
$client = new SoapClient('http://81.144.199.11/CRMWebService?wsdl',$action_authenticate);
$client->soap_defencoding = 'UTF-8';
// Call the SOAP method
$result = $client->call('AuthenticateUser', array('Username' => 'username', 'Password' => 'password'));
// Display the request and response
echo '<h2>Request</h2>';
echo '<pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2>';
echo '<pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
// Check for a fault
if ($client->fault) {
echo '<p><b>Fault: ';
print_r($result);
echo '</b></p>';
} else {
// Check for errors
$err = $client->getError();
if ($err) {
// Display the error
echo '<p><b>Error: ' . $err . '</b></p>';
} else {
// Display the result
print_r($result);
}
}
?>
Could anybody shed any light on this?
The problem here was that the web service was pointing at a local machine and my server couldn't translate that physical address from the IP address I needed to use to connect.
I had to ask for root access on my hosting server so I could edit the 'hosts' file with the IP address against the local machine, it was a simple line to add like this:
123.456.5.1 xxxdb01
I have a simple script to check if a server is online or offline, however this script doesn't seem to work on the servers I want.
This is the script:
$value = mysql_result($result,$i,"servername");
$value2 = mysql_result($result,$i,"serveraddress");
$value3 = mysql_result($result,$i,"portnumber");
$value4 = mysql_result($result,$i,"description");
$id = mysql_result($result,$i,"id");
ob_start();
if (!$socket = #fsockopen($value2, $value3, $errno, $errstr, 1))
{
echo " <font color='red'><CENTRE><strong>OFFLINE</strong></CENTRE></font>";
}
else
{
echo " <font color='green'><CENTRE><strong>ONLINE</strong></CENTRE></font>";
fclose($socket);
}
$status = ob_get_contents();
ob_end_clean();
?>
The problem is if I say use a Google address and port 80 it will show Google's online, if I use an external IP address and a port like 7000 or so it won't show if the server is online, despite it being online. I'm not sure why this is, I'm thinking its possibly because no data is being sent through the port at the time showing it's closed.
Can someone shed some light on this please and maybe rectify the situation.
So anyways, I'm working on a small PHP website/script, and as one of the features I'd like to be able to run a WHOIS lookup on the current domain the PHP script is running on.
Ideally, it would be one function that I could call and in the function it would run the WHOIS, and then echo the results to the screen. It would take in the URL of the site to run the WHOIS lookup on, or it would just run it on the current URL/Domain (which is what I want), although I can feed it a variable for the website domain if need be.
I don't know much about WHOIS lookups (well, I know what they do, I just don't know how to run them in PHP), but I'd also be fine with having to query another website (even one of my own if you can give me the code for it).
Whatever works, please just let me know! The main thing is that, I'd prefer it to fit all in one function, and it definitely must fit in one PHP file/document.
With php you can use shell_exec to execute the whois command.
<?php
$whois = shell_exec("whois domain.net");
echo '<pre>';
print_r($whois);
?>
This should do exactly what you want... http://www.phpwhois.org/
I've used this class before, doing exactly what you want!
To take Pavels answer one step further - this will break it down in to an array:
$whois = shell_exec("whois 45.118.135.255");
$result = explode("\n",$whois);
$out = array();
foreach ($result as $line){
if (substr($line,0,1) == '%' || substr($line,0,1) == '#'){ continue; }
$ps = explode(':',$line);
$out[trim($ps[0])] = trim($ps[1]);
}
print '<pre>'; print_r($out); print '</pre>';
There are some third party packages:
First one : io-developer/php-whois
composer require io-developer/php-whois
Usage:
// How to get summary about domain:
<?php
use Iodev\Whois\Factory;
// Creating default configured client
$whois = Factory::get()->createWhois();
// Checking availability
if ($whois->isDomainAvailable("google.com")) {
print "Bingo! Domain is available! :)";
}
// Supports Unicode (converts to punycode)
if ($whois->isDomainAvailable("почта.рф")) {
print "Bingo! Domain is available! :)";
}
// Getting raw-text lookup
$response = $whois->lookupDomain("google.com");
print $response->text;
// Getting parsed domain info
$info = $whois->loadDomainInfo("google.com");
print_r([
'Domain created' => date("Y-m-d", $info->creationDate),
'Domain expires' => date("Y-m-d", $info->expirationDate),
'Domain owner' => $info->owner,
]);
// Exceptions on domain lookup:
<?php
use Iodev\Whois\Factory;
use Iodev\Whois\Exceptions\ConnectionException;
use Iodev\Whois\Exceptions\ServerMismatchException;
use Iodev\Whois\Exceptions\WhoisException;
try {
$whois = Factory::get()->createWhois();
$info = $whois->loadDomainInfo("google.com");
if (!$info) {
print "Null if domain available";
exit;
}
print $info->domainName . " expires at: " . date("d.m.Y H:i:s", $info->expirationDate);
} catch (ConnectionException $e) {
print "Disconnect or connection timeout";
} catch (ServerMismatchException $e) {
print "TLD server (.com for google.com) not found in current server hosts";
} catch (WhoisException $e) {
print "Whois server responded with error '{$e->getMessage()}'";
}
If you are using Laravel : laravel-whois
composer require larva/laravel-whois -vv
php artisan migrate
Usage:
$info = \Larva\Whois\Whois::lookup('baidu.com', true);
$info = \Larva\Whois\Whois::lookupRaw('google.com');
Best thing to do would be to use pywhois. Though you say Python in the question title but don't mention it in the post. If you actually need PHP, I'm sure there's something equivalent for that.
I found it here: https://whoisfreaks.com/documentation/api/whois-api.html. You can get Whoislook up by using PHP thru this code snippet:
'https://api.whoisfreaks.com/v1.0/whois?whois=live&domainName=jfreaks.com&apikey=Your API_Key',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
I hope it'll work for you too.
Try the Function Which is available in github gist
https://gist.github.com/ManojKiranA/4b034659e85fa02308ad9bdcdd05629c
For the full list of TLDs/Whois servers see http://www.iana.org/domains/root/db/ and http://www.whois365.com/en/listtld/
How do I find out the ISP provider of a person viewing a PHP page?
Is it possible to use PHP to track or reveal it?
If I use something like the following:
gethostbyaddr($_SERVER['REMOTE_ADDR']);
it returns my IP address, not my host name or ISP.
This seems to be what you're looking for, it will attempt to return the full hostname if possible:
http://us3.php.net/gethostbyaddr
EDIT: This method no longer works since the website it hits now blocks automatic queries (and previously this method violated the website's terms of use). There are several other good [legal!] answers below (including my alternative this this one.)
You can get all those things from the following PHP codings.,
<?php
$ip=$_SERVER['REMOTE_ADDR'];
$url=file_get_contents("http://whatismyipaddress.com/ip/$ip");
preg_match_all('/<th>(.*?)<\/th><td>(.*?)<\/td>/s',$url,$output,PREG_SET_ORDER);
$isp=$output[1][2];
$city=$output[9][2];
$state=$output[8][2];
$zipcode=$output[12][2];
$country=$output[7][2];
?>
<body>
<table align="center">
<tr><td>ISP :</td><td><?php echo $isp;?></td></tr>
<tr><td>City :</td><td><?php echo $city;?></td></tr>
<tr><td>State :</td><td><?php echo $state;?></td></tr>
<tr><td>Zipcode :</td><td><?php echo $zipcode;?></td></tr>
<tr><td>Country :</td><td><?php echo $country;?></td></tr>
</table>
</body>
There is nothing in the HTTP headers to indicate which ISP a user is coming from, so the answer is no, there is no PHP builtin function which will tell you this. You'd have to use some sort of service or library which maps IPs to networks/ISPs.
Why not use ARIN's REST API.
<?php
// get IP Address
$ip=$_SERVER['REMOTE_ADDR'];
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, 'http://whois.arin.net/rest/ip/' . $ip);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
// execute
$returnValue = curl_exec($ch);
// close cURL resource, and free up system resources
curl_close($ch);
$result = json_decode($returnValue);
echo <<<END
<pre>
Handle: {$result->net->handle->{'$'}}
Ref: {$result->net->ref->{'$'}}
Name: {$result->net->name->{'$'}}
echo "OrgRef: {$result->net->orgRef->{'#name'}}";
</pre>
END;
// eof
https://www.arin.net/resources/whoisrws/whois_api.html
Sometimes fields change, so this is the improvement of the above post.
<body>
<table align="center">
<?
$ip=$_SERVER['REMOTE_ADDR'];
$url=file_get_contents("http://whatismyipaddress.com/ip/$ip");
preg_match_all('/<th>(.*?)<\/th><td>(.*?)<\/td>/s',$url,$output,PREG_SET_ORDER);
for ($q=0; $q < 25; $q++) {
if ($output[$q][1]) {
if (!stripos($output[$q][2],"Blacklist")) {
echo "<tr><td>".$output[$q][1]."</td><td>".$output[$q][2]."</td></tr>";
}
}
}
?>
</table>
</body>
You can obtain this information from ipinfo.io or similar services.
<?php
/**
* Get ip info from ipinfo.io
*
* There are other services like this, for example
* http://extreme-ip-lookup.com/json/106.192.146.13
* http://ip-api.com/json/113.14.168.85
*
* source: https://stackoverflow.com/a/54721918/3057377
*/
function getIpInfo($ip = '') {
$ipinfo = file_get_contents("https://ipinfo.io/" . $ip);
$ipinfo_json = json_decode($ipinfo, true);
return $ipinfo_json;
}
function displayIpInfo($ipinfo_json) {
var_dump($ipinfo_json);
echo <<<END
<pre>
ip : {$ipinfo_json['ip']}
city : {$ipinfo_json['city']}
region : {$ipinfo_json['region']}
country : {$ipinfo_json['country']}
loc : {$ipinfo_json['loc']}
postal : {$ipinfo_json['postal']}
org : {$ipinfo_json['org']}
</pre>
END;
}
function main() {
echo("<h1>Server IP information</h1>");
$ipinfo_json = getIpInfo();
displayIpInfo($ipinfo_json);
echo("<h1>Visitor IP information</h1>");
$visitor_ip = $_SERVER['REMOTE_ADDR'];
$ipinfo_json = getIpInfo($visitor_ip);
displayIpInfo($ipinfo_json);
}
main();
?>
GeoIP will help you with this: http://www.maxmind.com/app/locate_my_ip
There is a php library for accessing geoip data: http://www.maxmind.com/app/php
Attention though, you need to put the geoip db on your machine in order to make it work, all instructions are there :)
You can't rely on either the IP address or the host name to know the ISP someone is using.
In fact he may not use an ISP at all, or he might be logged in through a VPN connection to his place of employment, from there using another VPN or remote desktop to a hosting service halfway around the world, and connect to you from that.
The ip address you'd get would be the one from either that last remote machine or from some firewall that machine is sitting behind which might be somewhere else again.
I've attempted to correct Ram Kumar's answer but whenever I would edit their post I would be temporarily banned and my changes were ignored. (As to why, I don't know, It was my first and only edit that I've ever made on this website.)
Since his post, his code does not work anymore due to website changes and the Administrator implementing basic bot checks (checking the headers):
<?php
$IP = $_SERVER['REMOTE_ADDR'];
$User_Agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0';
$Accept = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
$Accept_Language = 'en-US,en;q=0.5';
$Referer = 'http://whatismyipaddress.com/';
$Connection = 'keep-alive';
$HTML = file_get_contents("http://whatismyipaddress.com/ip/$IP", false, stream_context_create(array('http' => array('method' => 'GET', 'header' => "User-Agent: $User_Agent\r\nAccept: $Accept\r\nAccept-Language: $Accept_Language\r\nReferer: $Referer\r\nConnection: $Connection\r\n\r\n"))));
preg_match_all('/<th>(.*?)<\/th><td>(.*?)<\/td>/s', $HTML, $Matches, PREG_SET_ORDER);
$ISP = $Matches[3][2];
$City = $Matches[11][2];
$State = $Matches[10][2];
$ZIP = $Matches[15][2];
$Country = $Matches[9][2];
?>
<body>
<table align="center">
<tr><td>ISP :</td><td><?php echo $ISP;?></td></tr>
<tr><td>City :</td><td><?php echo $City;?></td></tr>
<tr><td>State :</td><td><?php echo $State;?></td></tr>
<tr><td>Zipcode :</td><td><?php echo $ZIP;?></td></tr>
<tr><td>Country :</td><td><?php echo $Country;?></td></tr>
</table>
</body>
Note that just supplying a user-agent would probably suffice and the additional headers are most likely not required, I just added them to make the request look more authentic.
If all these answers are not useful then you can try API way.
1.http://extreme-ip-lookup.com/json/[IP ADDRESS HERE]
EXAMPLE: http://extreme-ip-lookup.com/json/106.192.146.13
2.http://ip-api.com/json/[IP ADDRESS HERE]
EXAMPLE: http://ip-api.com/json/113.14.168.85
once it works for you don't forget to convert JSON into PHP.
I think you need to use some third party service (Possibly a web service) to lookup the IP and find the service provider.
go to http://whatismyip.com
this will give you your internet address. Plug that address into the database at http://arin.net/whois
<?php
$isp = geoip_isp_by_name('www.example.com');
if ($isp) {
echo 'This host IP is from ISP: ' . $isp;
}
?>
(PECL geoip >= 1.0.2)
geoip_isp_by_name — Get the Internet Service Provider (ISP) name
http://php.net/manual/ru/function.geoip-isp-by-name.php
A quick alternative. (This website allows up to 50 calls per minute.)
$json=file_get_contents("https://extreme-ip-lookup.com/json/$ip");
extract(json_decode($json,true));
echo "ISP: $isp ($city, $region, $country)<br>";
API details at the bottom of the page.
This is the proper way to find a isp from site or ip.
<?php
$isp = geoip_isp_by_name('www.example.com');
if ($isp) {
echo 'This host IP is from ISP: ' . $isp;
}
?>