Php tracking own location gives a randomized IP - php

-- 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_FORWARDE‌​D_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.

Related

Does Google Geocode work for anyone in 2018 is there an alternative?

Google Geocode use to work for me but does not anymore. Everything I've tried returns false. It doesn't even give a clue as to why. I've tried changing the API key, I've tried different methods to connect (I prefer using simplexml_load_file). It does work if I type the URL directly into the a browser window but not from my website or even from my localhost. Does anyone have suggestions on what to try next or an alternative to Googles Geocode service?
Here is some code that I've been using that Json / XML results.
//URL SAVE ADDRESS
date_default_timezone_set("America/Chicago");
$address = "1600 Amphitheatre Parkway, Mountain View, CA 94043";
$address = urlencode($address);
// GOOGLE URL
$url = "https://maps.googleapis.com/maps/api/geocode/xml?address=". $address ."&sensor=false&key=AIzaSyDrGe_qr4ofea8WhZFhnPGsXNQtTiQwGhw";
echo $url; //TEMP
$xml = simplexml_load_file($url) OR $ex['tblx'] = "Unable to load XML from Googleapis.";
if(empty($xml)) {
$ex['tblx'] = "Googleapis return no values.";
} elseif("" == $xml) {
$ex['tblx'] = "Geocode problem with address, revise and retry.";
} elseif("OK" != $xml->status) {
$ex['tblx'] = "Geocode: " . ("ZERO_RESULTS" == $xml->status? "Not Found": substr($xml->status,0,30));
} else{
$dvtby0 = $uca['y0'] = (double)$xml->result->geometry->location->lat; //x
$dvtbx0 = $uca['x0'] = (double)$xml->result->geometry->location->lng;
$dvtby1 = $uca['y1'] = (double)$xml->result->geometry->viewport->southwest->lat; //a
$dvtbx2 = $uca['x1'] = (double)$xml->result->geometry->viewport->southwest->lng;
$dvtbx1 = $uca['x2'] = (double)$xml->result->geometry->viewport->northeast->lng; //b
$dvtby2 = $uca['y2'] = (double)$xml->result->geometry->viewport->northeast->lat;
}//endif
if($ex) {
var_dump($ex);
}
die("did it work?");
geocoder.ca for north america
opencage or geocode.xyz for the world
pelias as standalone
there are lots of options in 2018
The problem here turned out to be the version of PHP. It's really weird and hard to troubleshoot. simplexml_load_file($url) was not returning an object. It wasn't even returning false. The only clue that it was something other that code problem. Upgrade to version 5.6 and it works ok.

php file_get_contents() returning false with a valid url

I'm currently working on a geocoding php function, using google maps API. Strangely, file_get_contents() returns bool(false) whereas the url I use is properly encoded, I think.
In my browser, when I test the code, the page takes a very long time to load, and the geocoding doesn't work (of course, given that the API doesn't give me what I want).
Also I tried to use curl, no success so far.
If anyone could help me, that'd be great !
Thanks a lot.
The code :
function test_geocoding2(){
$addr = "14 Boulevard Vauban, 26000 Valence";
if(!gc_geocode($addr)){
echo "false <br/>";
}
}
function gc_geocode($address){
$address = urlencode($address);
$url = "http://maps.google.com/maps/api/geocode/json?address={$address}";
$resp_json = file_get_contents($url);
$resp = json_decode($resp_json, true);
if($resp['status']=='OK'){
$lati = $resp['results'][0]['geometry']['location']['lat'];
$longi = $resp['results'][0]['geometry']['location']['lng'];
if($lati && $longi){
echo "(" . $lati . ", " . $longi . ")";
}else{
echo "data not complete <br/>";
return false;
}
}else{
echo "status not ok <br/>";
return false;
}
}
UPDATE : The problem was indeed the fact that I was behind a proxy. I tested with another network, and it works properly.
However, your answers about what I return and how I test the success are very nice as well, and will help me to improve the code.
Thanks a lot !
The problem was the fact that I was using a proxy. The code is correct.
To check if there is a proxy between you and the Internet, you must know the infrastructure of your network. If you work from a school or a company network, it is very likely that a proxy is used in order to protect the local network.
If you do not know the answer, ask your network administrator.
If there is no declared proxy in your network, it is still possible that a transparent proxy is there. However, as states the accepted answer to this question: https://superuser.com/questions/505772/how-can-i-find-out-if-there-is-a-proxy-between-myself-and-the-internet-if-there
If it's a transparent proxy, you won't be able to detect it on the client PC.
Some website also provide some proxy detectors, though I have no idea of how relevant is the information given there. Here are two examples :
http://amibehindaproxy.com/
http://www.proxyserverprivacy.com/free-proxy-detector.shtml
When you are not return anything function returns null.
Just use that:
if(!is_null(gc_geocode($addr))) {
echo "false <br/>";
}
Or:
if(gc_geocode($addr) === false) {
echo "false <br/>";
}
Take a look at the if statement:
if(!gc_geocode($addr)){
echo "false <br/>";
}
This means that if gc_geocode($addr) returns either false or null, this statement will echo "false".
However, you never actually return anything from the function, so on success, it's returning null:
$address = urlencode($address);
$url = "http://maps.google.com/maps/api/geocode/json?address={$address}";
$resp_json = file_get_contents($url);
$resp = json_decode($resp_json, true);
if($lati && $longi){
echo "(" . $lati . ", " . $longi . ")"; //ECHO isn't RETURN
/* You should return something here, e.g. return true */
} else {
echo "data not complete <br/>";
return false;
}
} else {
echo "status not ok <br/>";
return false;
}
Alternatively, you can just change the if statement to only fire when the function returns false:
if(gc_geocode($addr)===false){
//...
Above function gc_geocode() working properly on my system, without any extra load. You have called gc_geocode () it returns you lat, long that is correct now you have check through
if(!gc_geocode($addr)){
echo "false <br/>";
}
Use
if($responce=gc_geocode($addr)){
echo $responce;
}
else{
echo "false <br/>";
}

PHP does not resolve .local dns names with gethostbyname

I have werid problem with name resolution. I am trying to connect to active directory server. I can successfully get the ldap server address from the SRV recodrs. Then I try to resolve the dns names to IP addresses and it fails:
<?php
echo 'example.com.:' . PHP_EOL;
echo gethostbyname('example.com.');
echo PHP_EOL;
echo 'dc1.veracomp.local.:' . PHP_EOL;
echo gethostbyname('dc1.my-company.local.');
echo PHP_EOL;
echo 'nslookup dc1.my-company.local.:' . PHP_EOL;
echo `nslookup dc1.my-company.local.`;
The example.com is resolved correctly, then the gethostbyname('dc1.my-company.local.') fails after a few seconds returning dc1.my-company.local. instead of the IP address. Still the same PHP script can call nslookup which correctly resolves the domain name...:
example.com.:
93.184.216.119
dc1.my-company.local.:
dc1.my-company.local.
nslookup dc1.my-company.local.:
Server: xxx.xxx.254.117
Address: xxx.xxx.254.117#53
Name: dc1.my-company.local
Address: 192.168.12.21
What is wrong here?
EDIT:
I am asking for name resolution beacuse the real problem i have is that I can connect to ldap://192.168.12.21 or to ldap://dc1.my-company.pl, but I cannot connect to ldap://dc1.my-company.local.
Unfortunatelly the SRV records for _ldap._tcp.my-company.pl returns only local addresses. I do not want to hardcode the .pl address. And I do not understand why I have to manually resolve the local addresses before passing them to Zend_Ldap as a host option.
You should avoid its use in production. DNS Resolution may take from 0.5 to 4 seconds, and during this time your script is NOT being executed.
I use this one; this will be faster and more efficient:
<?php
function getAddrByHost($hosts, $timeout = 3) {
$returnString = '';
foreach ($hosts as $host) {
$query = `nslookup -timeout=$timeout -retry=1 $host`;
if (preg_match('/\nAddress: (.*)\n/', $query, $matches))
$returnString .= trim($matches[1]) . '<br>';
$returnString .= $host . '<br>';
}
return $returnString;
}
$hostArray[] = 'www.example.com';
$hostArray[] = 'dc1.my-company.local';
$returnString = getAddrByHost($hostArray);
echo $returnString;
?>

PHP to return gethostbyname($lookup) value

I am using the code below (simplified version) to determine if my IPs are on a blacklist. I need to modify it to be able to determine if an IP is on a Whitelist. The function will require me to see a specific code returned.
127.0.0.1
127.0.0.2
127.0.0.3
127.0.0.4
127.0.0.5
How can this be adjusted to return the (code) output value when the script runs?
$host = '222.22.222.222';
$rbl = 'hostkarma.junkemailfilter.com';
$rev = array_reverse(explode('.', $host));
$lookup = implode('.', $rev) . '.' . $rbl;
if ($lookup != gethostbyname($lookup)) {
echo "ip: $host is listed in $rbl\n";
} else {
echo "ip: $host NOT listed in $rbl\n";
}
EDIT: Sorry guys, The function of the script above will return confirmation if the IP address is on the blacklist entered in $rlb. However, Hostkarma returns a code, one of the 127.0 codes shown above as each code indicates a different block status. I need to get the code. "echo $lookup;" just returns the reverse lookup, like this: 222.222.22.222.hostkarma.junkemailfilter.com
$lookup = implode('.', $rev) . '.' . $rbl;
$value = gethostbyname($lookup);
if ($lookup != $value){
echo "ip: $host is listed in $rbl\n";
echo "return value: $value\n";
}
else{
echo "ip: $host NOT listed in $rbl\n";
}
The 127.x.x.x code should be given to you as the value returned by gethostbyname.
Do you mean this?
echo $lookup;

How do I retrieve the visitor's ISP through PHP?

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

Categories