{"id":64771,"date":"2024-09-23T03:01:00","date_gmt":"2024-09-22T17:01:00","guid":{"rendered":"https:\/\/www.rjmprogramming.com.au\/ITblog\/?p=64771"},"modified":"2024-09-22T21:39:00","modified_gmt":"2024-09-22T11:39:00","slug":"php-geoip-primer-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/php-geoip-primer-tutorial\/","title":{"rendered":"PHP GeoIP Primer Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/geoip_hostname.php\" rel=\"noopener\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"PHP GeoIP Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/geoip_hostname.gif\" title=\"PHP GeoIP Primer Tutorial\"  style=\"float:left;\"  \/><\/a><p class=\"wp-caption-text\">PHP GeoIP Primer Tutorial<\/p><\/div>\n<p>Today, we wanted to enter the world of <a target=\"_blank\" title=\"GeoIP\" href='https:\/\/www.maxmind.com\/en\/geoip-demo' rel=\"noopener\">GeoIP<\/a>, which, as the name suggests, is gleaning information about the &#8220;where&#8221; of life given an &#8230;<\/p>\n<ul>\n<li><a target=\"_blank\" title='IP address information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/IP_address' rel=\"noopener\">IP address<\/a> &#8230; known directly &#8230; or discernible via a &#8230;<\/li>\n<li>domain or host name<\/li>\n<\/ul>\n<p> &#8230; making use of databases provided by the great <a target=\"_blank\" title=\"MaxMind\" href='\/\/www.maxmind.com\/' rel=\"noopener\">MaxMind<\/a> open source resource we established an account with, allowing us to download database CSV data (for our desires) that is updated on a regular basis.<\/p>\n<p>Originally we thought we&#8217;d be using PHP to host Python &#8230;<\/p>\n<p><code><br \/>\n# getting us, on AlmaLinux, installing via ...<br \/>\n$ dnf list *geo*ip*<br \/>\n$ dnf install python3-geoip2<br \/>\n$ pip install python-geoip<br \/>\n$ pip install python-geoip-geolite2<br \/>\n$ pip3 install maxminddb<br \/>\n$ pip3 install maxminddb-geolite2<br \/>\n<\/code><\/p>\n<p> &#8230; and then register with <a target=\"_blank\" title=\"MaxMind\" href='\/\/www.maxmind.com\/' rel=\"noopener\">MaxMind<\/a> after this, <a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/geoip_hostname.gif\" rel=\"noopener\">to help make this solution happen<\/a>, but ended up combining the (just) PHP supervision of &#8230;<\/p>\n<ul>\n<li><a target=\"_blank\" title='ping information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Ping_(networking_utility)' rel=\"noopener\">ping<\/a> &#8230; means (via PHP shell_exec), as required, to derive an IP address from a host or domain name &#8230; then &#8230;<\/li>\n<li>PHP &#8230; means by which <a target=\"_blank\" title=\"MaxMind\" href='\/\/www.maxmind.com\/' rel=\"noopener\">MaxMind<\/a> CSV files are scoured to link IP address to geodata of interest, to derived City and Country of interest information<\/li>\n<\/ul>\n<p> &#8230; via a first draft &#8230;<\/p>\n<p><code><br \/>\n&lt;?php<br \/>\n\/\/ geoip_hostname.php<br \/>\n\/\/ RJM Programming<br \/>\n\/\/ September, 2024<br \/>\n\/\/ Thanks to GeoIP<br \/>\n<br \/>\n  $city='';<br \/>\n  $country='';<br \/>\n  $state='';<br \/>\n  $ccode='';<br \/>\n  $tzplace='';<br \/>\n  $continent='';<br \/>\n  $newhname='';<br \/>\n  $preresults='';<br \/>\n  $results='';<br \/>\n  $hname='';<br \/>\n  $via='';<br \/>\n  if (isset($_GET['via']) || isset($_POST['via'])) {<br \/>\n      $via='' . (isset($_GET['via']) ? str_replace('+',' ',urldecode($_GET['via'])) : '') . (isset($_POST['via']) ? str_replace('+',' ',urldecode($_POST['via'])) : '');<br \/>\n  }<br \/>\n  if (isset($_GET['hostname']) || isset($_POST['hostname'])) {<br \/>\n      $hname='' . (isset($_GET['hostname']) ? str_replace('+',' ',urldecode($_GET['hostname'])) : '') . (isset($_POST['hostname']) ? str_replace('+',' ',urldecode($_POST['hostname'])) : '');<br \/>\n      if ($via == $hname) { $via=''; }<br \/>\n  }<br \/>\n  <br \/>\n  if (trim($hname) != '') {<br \/>\n    if (substr(trim($hname),0,1) &lt; '0' || substr(trim($hname),0,1) &gt; '9') {<br \/>\n    if (strpos($hname, '\/\/') === false) {<br \/>\n       $hname='http:\/\/' . $hname;<br \/>\n    } else if (strpos($hname, ':') === false) {<br \/>\n       $hname='http:' . $hname;<br \/>\n    }<br \/>\n    \/\/$bigcont=file_get_contents($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'ip_example.py');<br \/>\n    \/\/file_put_contents('\/tmp\/ip_example_ours.py', str_replace(explode(\"'\", explode(\"url = '\", $bigcont)[1])[0], $hname, $bigcont));<br \/>\n    \/\/echo    '\/usr\/bin\/python ' . $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'test_geoip.py --hostname=' . $hname;<br \/>\n    \/\/exit;<br \/>\n    if (1 == 1) {<br \/>\n    $results=shell_exec('ping -c 4 ' . str_replace('http:\/\/','',$hname));<br \/>\n    } else {<br \/>\n    $results=shell_exec('\/usr\/bin\/python ' . $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'test_geoip.py --hostname=' . str_replace('http:\/\/','',$hname));<br \/>\n    }<br \/>\n    if (strpos($results, 'PING ' . str_replace('http:\/\/','',$hname) . ' (') !== false) {<br \/>\n      $newhname=explode(\" \",explode(\")\",trim(explode('PING ' . str_replace('http:\/\/','',$hname) . ' (', $results)[1]))[0])[0];<br \/>\n      $results='';<br \/>\n    } else if (strpos($results, 'IP address:') !== false) {<br \/>\n      $newhname=explode(\" \",explode(\"\\n\",trim(explode('IP address:', $results)[1]))[0])[0];<br \/>\n      $results='';<br \/>\n    }<br \/>\n  } else if ($hname != '') {<br \/>\n    if ($via != '' && (substr(trim($via),0,1) &lt; '0' || substr(trim($via),0,1) &gt; '9')) {<br \/>\n    $preresults='Looking up ' . $via . \" ( \" . $hname . \" ) \";<br \/>\n    } else {<br \/>\n    $preresults='Looking up ' . $hname;<br \/>\n    }<br \/>\n    $gnames=',';<br \/>\n    foreach (glob('\/tmp\/GeoLite2-City-CSV_20240920\/GeoLite2-City-Blocks-IP*.csv') as $fname) {<br \/>\n       $fgc='';<br \/>\n       if (1 == 1) {<br \/>\n         $fgc=\"\\n\" . shell_exec('fgrep \"' . $hname . '\/\" ' . $fname) . \"\\n\";<br \/>\n       } else {<br \/>\n         $fgc=\"\\n\" . file_get_contents($fname) . \"\\n\";<br \/>\n       }<br \/>\n       $listis=\"\\n\" . $fgc . \"\\n\";<br \/>\n       if (strpos($listis, \"\\n\" . $hname . \"\/\") !== false) {<br \/>\n         $lis=explode(\"\\n\" . $hname . \"\/\", $listis);<br \/>\n         for ($ii=1; $ii&lt;sizeof($lis); $ii++) {<br \/>\n           $cols=explode(',',$lis[$ii]);<br \/>\n           if ($cols[1] != '') {<br \/>\n            if (strpos($gnames, ',' . $cols[1] . ',') === false) {<br \/>\n             $gnames.=$cols[1] . ',';<br \/>\n            }<br \/>\n           }<br \/>\n         }<br \/>\n       }<br \/>\n    }<br \/>\n    if ($gnames != ',') {<br \/>\n    $garr=explode(',', substr($gnames,1,(-2 + strlen($gnames))));<br \/>\n    foreach (glob('\/tmp\/GeoLite2-City-CSV_20240920\/GeoLite2-City-Locations-*.csv') as $fname) {<br \/>\n       for ($jj=0; $jj&lt;sizeof($garr); $jj++) {<br \/>\n       $fgc='';<br \/>\n       if (1 == 1) {<br \/>\n         $fgc=\"\\n\" . shell_exec('fgrep \"' . $garr[$jj] . ',\" ' . $fname) . \"\\n\";<br \/>\n       } else {<br \/>\n         $fgc=\"\\n\" . file_get_contents($fname) . \"\\n\";<br \/>\n       }<br \/>\n       $listis=\"\\n\" . $fgc . \"\\n\";<br \/>\n       if (strpos($listis, \"\\n\" . $garr[$jj] . \",\") !== false) {<br \/>\n         $lis=explode(\"\\n\" . $garr[$jj] . \",\", $listis);<br \/>\n         for ($ii=1; $ii&lt;sizeof($lis); $ii++) {<br \/>\n           $cols=explode(',',$lis[$ii]);<br \/>\n           if ($cols[3] != '') {<br \/>\n            if ($ccode == '') { $ccode='&lt;table border=1 style=width:80%;&gt;&lt;tr&gt;&lt;td&gt;'; }<br \/>\n            $ccode.=' ' . str_replace('\"','',$cols[3]) . '&lt;\/td&gt;&lt;td&gt;';<br \/>\n           }<br \/>\n           if ($cols[4] != '') {<br \/>\n            if ($country == '') { $country='&lt;table border=1  style=width:80%;&gt;&lt;tr&gt;&lt;td&gt;'; }<br \/>\n            $country.=' ' . str_replace('\"','',$cols[4]) . '&lt;\/td&gt;&lt;td&gt;';<br \/>\n           }<br \/>\n           if ($cols[9] != '') {<br \/>\n            if ($city == '') { $city='&lt;table border=1  style=width:80%;&gt;&lt;tr&gt;&lt;td&gt;'; }<br \/>\n            $city.=' ' . str_replace('\"','',$cols[9]) . '&lt;\/td&gt;&lt;td&gt;';<br \/>\n           }<br \/>\n           if ($cols[6] != '') {<br \/>\n            if ($state == '') { $state='&lt;table border=1  style=width:80%;&gt;&lt;tr&gt;&lt;td&gt;'; }<br \/>\n            $state.=' ' . str_replace('\"','',$cols[6]) . '&lt;\/td&gt;&lt;td&gt;';<br \/>\n           }<br \/>\n           if ($cols[11] != '') {<br \/>\n            if ($tzplace == '') { $tzplace='&lt;table border=1  style=width:80%;&gt;&lt;tr&gt;&lt;td&gt;'; }<br \/>\n            $tzplace.=str_replace(' NA',' ',' ' . str_replace('\"','',$cols[1])) . '&lt;\/td&gt;&lt;td&gt;';<br \/>\n           }<br \/>\n           if ($cols[2] != '') {<br \/>\n            if ($continent == '') { $continent='&lt;table border=1  style=width:80%;&gt;&lt;tr&gt;&lt;td&gt;'; }<br \/>\n            $continent.=' ' . str_replace('\"','',$cols[2]) . '&lt;\/td&gt;&lt;td&gt;';<br \/>\n           }<br \/>\n         }<br \/>\n       }<br \/>\n       }<br \/>\n       $results=\"&lt;br&gt;&lt;br&gt;City: \" . ($city == '' ? $city : $city . '&lt;\/td&gt;&lt;\/tr&gt;&lt;\/table&gt;') . \"\\nState: \" . ($state == '' ? $state : $state . '&lt;\/td&gt;&lt;\/tr&gt;&lt;\/table&gt;') . \"\\nCountry: \" . ($country == '' ? $country : $country . '&lt;\/td&gt;&lt;\/tr&gt;&lt;\/table&gt;') . \"\\nCountry Code: \" . ($ccode == '' ? $ccode : $ccode . '&lt;\/td&gt;&lt;\/tr&gt;&lt;\/table&gt;') . \"\\nContinent: \" . ($continent == '' ? $continent : $continent . '&lt;\/td&gt;&lt;\/tr&gt;&lt;\/table&gt;') . \"\\nTimezone: \" . ($tzplace == '' ? $tzplace : $tzplace . '&lt;\/td&gt;&lt;\/tr&gt;&lt;\/table&gt;') . \"&lt;br&gt;&lt;br&gt;\";<br \/>\n    }<br \/>\n    }<br \/>\n  }<br \/>\n  }<br \/>\n  <br \/>\n  echo \"&lt;html&gt;<br \/>\n&lt;head&gt;<br \/>\n&lt;title&gt;Hostname Lookup geoip_hostname.php - RJM Programming - September, 2024&lt;\/title&gt;<br \/>\n&lt;\/head&gt;<br \/>\n&lt;body onload=\\\" if (document.getElementById('hostname').value != '') { setTimeout(function() { document.getElementById('blook').click(); }, 2000);  } \\\"&gt;<br \/>\n&lt;h1&gt;Hostname Lookup&lt;\/h1&gt;<br \/>\n&lt;h3&gt;RJM Programming - September, 2024 ... thanks to &lt;a target=_blank title=MaxMind href='\/\/www.maxmind.com\/'&gt;MaxMind&lt;\/a&gt;&lt;\/h3&gt;<br \/>\n&lt;div id=results&gt;\" . $preresults . str_replace(\"\\n\",\"&lt;br&gt;\",$results) . \"&lt;\/div&gt;&lt;br&gt;&lt;br&gt;<br \/>\n&lt;form method=POST action=.\/geoip_hostname.php&gt;<br \/>\n&lt;input style=width:80%; type=text name=hostname id=hostname placeholder='Enter host name or domain name or host IP address to show information regarding ...' value='\" . $newhname . \"'&gt;&lt;\/input&gt;&lt;br&gt;&lt;br&gt;<br \/>\n&lt;input type=hidden name=via id=via value='\" . $hname . \"'&gt;&lt;\/input&gt;<br \/>\n&lt;input type=submit id=blook value=Lookup&gt;&lt;\/input&gt;<br \/>\n&lt;\/form&gt;<br \/>\n&lt;\/body&gt;<br \/>\n&lt;\/html&gt;\";<br \/>\n<br \/>\n  exit;<br \/>\n?&gt;<br \/>\n<\/code><\/p>\n<p> &#8230; in a <a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/geoip_hostname.php_GETME\" rel=\"noopener\">first draft<\/a> <a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/geoip_hostname.php\" rel=\"noopener\">GeoIP using PHP web application<\/a> you can <a href='#ageoipif'>also try below<\/a> &#8230;<\/p>\n<p><iframe style='width:95%;height:700px;' id='ageoipif' src='\/\/www.rjmprogramming.com.au\/geoip_hostname.php'><\/iframe><\/p>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d64756' onclick='var dv=document.getElementById(\"d64771\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/country\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d64771' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Today, we wanted to enter the world of GeoIP, which, as the name suggests, is gleaning information about the &#8220;where&#8221; of life given an &#8230; IP address &#8230; known directly &#8230; or discernible via a &#8230; domain or host name &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/php-geoip-primer-tutorial\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,37],"tags":[283,299,355,480,4924,2979,4926,629,3862,4925,932,1740,997,1012,3942,1319],"class_list":["post-64771","post","type-post","status-publish","format-standard","hentry","category-elearning","category-tutorials","tag-csv","tag-database-2","tag-domain","tag-geodata","tag-geoip","tag-host","tag-host-name","tag-ip-address","tag-lookup","tag-maxmind","tag-php","tag-ping","tag-programming","tag-python","tag-shell_exec","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/64771"}],"collection":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/comments?post=64771"}],"version-history":[{"count":10,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/64771\/revisions"}],"predecessor-version":[{"id":64784,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/64771\/revisions\/64784"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=64771"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=64771"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=64771"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}