I am using this function to get the two-letter country code:
$ipaddress = $_SERVER['REMOTE_ADDR'];
function ip_details($ip) {
$json = file_get_contents("http://ipinfo.io/{$ip}");
$details = json_decode($json);
return $details;
}
$details = ip_details($ipaddress);
echo $details->country;
Output:
US // Two-letter Country Code
And to make a log in a file, I was thinking of using something like this:
$file = 'visitors.txt';
file_put_contents($file, $ipaddress . PHP_EOL, FILE_APPEND);
Output:
xxx.xxx.xxx.xx // with a line break after
I want to loop through the country codes and display them with the number of visitors from each country. For example:
If two IP Addresses from US and 1 IP Address from Canada went on the page... I want to display:
US: 2
CA: 1
Any help will be appreciated.
Although I don't like the idea of working with text files here - here is an easy solution for that task (untested):
<?php
// Setup.
$pathVisitorsFile = 'visitors.txt';
// Execution.
if(!file_exists($pathVisitorsFile)) {
die('File "'. $pathVisitorsFile .'" not found');
}
// Read entries.
$visitorsCountry = file($pathVisitorsFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// Count entries.
$foundCountries = array();
foreach($visitorsCountry as $visitorCountry) {
if(!isset($foundCountries[$visitorCountry])) {
$foundCountries[$visitorCountry] = 1;
} else {
$foundCountries[$visitorCountry]++;
}
}
// Display entries.
echo('<ul>');
foreach($foundCountries as $countryCode => $visitors) {
echo('<li>'. $countryCode .': '. $visitors .'</li>');
}
echo('</ul>');
?>
I assumed that you already have a file with contents like:
US
US
US
DE
DE
IR
AT
US
Related
Below code works great with getting only a bunch IP address and add it to Cacti --description='".$dev."' --ip='".$dev."', now I want to add bunch of IP with their description in cacti forexample(--description='".$hostname."' --ip='".$dev."').
I am newbie to PHP and don't know how to add 2 values instead of 1 value in PHP.
devices.txt
1.1.1.1
add_device_bulk.php
if ($handle) {
while (($line = fgets($handle)) !== false) {
$line = chop($line);
print "[".$line."] \n";
createHost($line);
}
} else {
die("Could not open file $filename!");
}
die;
function createHost($dev)
{
global $community;
global $hosttemplate;
print "================== Creating Node & Graph for $dev =======================\n";
$ret = cmd("/usr/bin/php add_device.php --quiet --description='".$dev."' --ip='".$dev."' --template=$hosttemplate --community='".$community."' --avail=snmp ");
//Get host id from: [RET] Success - new device-id: (20)
if (preg_match("/\((\d+)\)/", $ret, $matches))
{
$deviceID = $matches[1];
print "Device ID: $deviceID \n";
//We got a device - create graphs for device
$ret = cmd("/usr/bin/php add_graphs.php --graph-type=ds --graph-template-id=5 --host-id=".$deviceID." --snmp-query-id=1 --snmp-query-type-id=10 --snmp-field=ifOperStatus --snmp-value-regex=Up --snmp-field=ifDescr --snmp-value-regex='GigabitEthernet'");
//RET: Graph Added - graph-id: (34) - data-source-ids: (37, 37)
if (preg_match("/\((\d+)\)/", $ret, $matches)) {
$graphID = $matches[1];
//We got a graph - add it to default tree
# cmd("/usr/bin/php /cacti/appl/cacti/cli/add_tree.php --type=node --node-type=graph --tree-id=1 --graph-id=".$graphID);
}
}
}
function cmd($cmd)
{
print "[CMD] $cmd\n";
$ret = exec($cmd)."\n";
print "[RET] $ret\n";
return $ret;
}
Now I want to add description instead of IP and have a text file as below:
devices.txt
Link1, 1.1.1.1
I know this can be done in mysql but I want the IP to be stored in php or a text file and its kinda hard for me because I do not quite understand it.
$SESSION is used to log but how can it be stored and banned for 24 hours after a html button is clicked.
Many thanks
Something like this should do the trick.
We write the visitors IP and the time that the ban expires to a text file. We then load this and check if they are in that file, and still banned.
function ban()
{
$ip = $_SERVER['REMOTE_ADDR'];
file_put_contents(
'bans.txt',
sprintf("%s;%s\n", $ip, (new DateTime())->add(new DateInterval('PT24H'))->getTimestamp()),
FILE_APPEND | LOCK_EX);
}
function checkBan()
{
$ip = $_SERVER['REMOTE_ADDR'];
$bans = file('bans.txt');
foreach ($bans as $ban) {
$banExpiry = (int) explode(';', $ban)[1];
if ($banExpiry < time()) {
continue;
}
$bannedIp = explode(';', $ban)[0];
if ($bannedIp === $ip) {
return true;
}
}
return false;
}
I have a small website (using HTML, PHP and MySQL), and would like to display a specific banner image according to the country of the visitor. Each country has a different banner image.
I have searched Google for solutions and found quite some API's (such as HostIP) that allow to return the country based upon the IP address. That's nice, but I could not find how to implement it for my purpose to make the image switch according to the country...
I have no developer knowledge. Can anyone help me out?
Get Geo-IP Information
Requests a geo-IP-server (netip.de) to check, returns where an IP is located (host, state, country, town).
<?php
$ip='94.219.40.96';
print_r(geoCheckIP($ip));
//Array ( [domain] => dslb-094-219-040-096.pools.arcor-ip.net [country] => DE - Germany [state] => Hessen [town] => Erzhausen )
//Get an array with geoip-infodata
function geoCheckIP($ip)
{
//check, if the provided ip is valid
if(!filter_var($ip, FILTER_VALIDATE_IP))
{
throw new InvalidArgumentException("IP is not valid");
}
//contact ip-server
$response=#file_get_contents('http://www.netip.de/search?query='.$ip);
if (empty($response))
{
throw new InvalidArgumentException("Error contacting Geo-IP-Server");
}
//Array containing all regex-patterns necessary to extract ip-geoinfo from page
$patterns=array();
$patterns["domain"] = '#Domain: (.*?) #i';
$patterns["country"] = '#Country: (.*?) #i';
$patterns["state"] = '#State/Region: (.*?)<br#i';
$patterns["town"] = '#City: (.*?)<br#i';
//Array where results will be stored
$ipInfo=array();
//check response from ipserver for above patterns
foreach ($patterns as $key => $pattern)
{
//store the result in array
$ipInfo[$key] = preg_match($pattern,$response,$value) && !empty($value[1]) ? $value[1] : 'not found';
}
return $ipInfo;
}
?>
to complete the anwer of Avinash, is this the right solution to switch image based upon country?
function switchImage($var) {
switch ($var)
{
case "United states":
$source = '/images/US.png';
$class = 'myClass';
$alt = 'myAlt';
break;
case "United Kingdom":
$source = '/images/UK.png';
$class = 'myClass';
$alt = 'myAlt';
break;
.
.
.
default:
return "Default"; //default case
}
}
I know there is a LOT of info on the web regarding to this subject but I can't seem to figure it out the way I want.
I'm trying to build a function which strips the domain name from a url:
http://blabla.com blabla
www.blabla.net blabla
http://www.blabla.eu blabla
Only the plain name of the domain is needed.
With parse_url I get the domain filtered but that is not enough.
I have 3 functions that stips the domain but still I get some wrong outputs
function prepare_array($domains)
{
$prep_domains = explode("\n", str_replace("\r", "", $domains));
$domain_array = array_map('trim', $prep_domains);
return $domain_array;
}
function test($domain)
{
$domain = explode(".", $domain);
return $domain[1];
}
function strip($url)
{
$url = trim($url);
$url = preg_replace("/^(http:\/\/)*(www.)*/is", "", $url);
$url = preg_replace("/\/.*$/is" , "" ,$url);
return $url;
}
Every possible domain, url and extension is allowed. After the function is finished, it must return a array of only the domain names itself.
UPDATE:
Thanks for all the suggestions!
I figured it out with the help from you all.
function test($url)
{
// Check if the url begins with http:// www. or both
// If so, replace it
if (preg_match("/^(http:\/\/|www.)/i", $url))
{
$domain = preg_replace("/^(http:\/\/)*(www.)*/is", "", $url);
}
else
{
$domain = $url;
}
// Now all thats left is the domain and the extension
// Only return the needed first part without the extension
$domain = explode(".", $domain);
return $domain[0];
}
How about
$wsArray = explode(".",$domain); //Break it up into an array.
$extension = array_pop($wsArray); //Get the Extension (last entry)
$domain = array_pop($wsArray); // Get the domain
http://php.net/manual/en/function.array-pop.php
Ah, your problem lies in the fact that TLDs can be either in one or two parts e.g .com vs .co.uk.
What I would do is maintain a list of TLDs. With the result after parse_url, go over the list and look for a match. Strip out the TLD, explode on '.' and the last part will be in the format you want it.
This does not seem as efficient as it could be but, with TLDs being added all the time, I cannot see any other deterministic way.
Ok...this is messy and you should spend some time optimizing and caching previously derived domains. You should also have a friendly NameServer and the last catch is the domain must have a "A" record in their DNS.
This attempts to assemble the domain name in reverse order until it can resolve to a DNS "A" record.
At anyrate, this was bugging me, so I hope this answer helps :
<?php
$wsHostNames = array(
"test.com",
"http://www.bbc.com/news/uk-34276525",
"google.uk.co"
);
foreach ($wsHostNames as $hostName) {
echo "checking $hostName" . PHP_EOL;
$wsWork = $hostName;
//attempt to strip out full paths to just host
$wsWork = parse_url($hostName, PHP_URL_HOST);
if ($wsWork != "") {
echo "Was able to cleanup $wsWork" . PHP_EOL;
$hostName = $wsWork;
} else {
//Probably had no path info or malformed URL
//Try to check it anyway
echo "No path to strip from $hostName" . PHP_EOL;
}
$wsArray = explode(".", $hostName); //Break it up into an array.
$wsHostName = "";
//Build domain one segment a time probably
//Code should be modified not to check for the first segment (.com)
while (!empty($wsArray)) {
$newSegment = array_pop($wsArray);
$wsHostName = $newSegment . $wsHostName;
echo "Checking $wsHostName" . PHP_EOL;
if (checkdnsrr($wsHostName, "A")) {
echo "host found $wsHostName" . PHP_EOL;
echo "Domain is $newSegment" . PHP_EOL;
continue(2);
} else {
//This segment didn't resolve - keep building
echo "No Valid A Record for $wsHostName" . PHP_EOL;
$wsHostName = "." . $wsHostName;
}
}
//if you get to here in the loop it could not resolve the host name
}
?>
try with preg_replace.
something like
$domain = preg_replace($regex, '$1', $url);
regex
function test($url)
{
// Check if the url begins with http:// www. or both
// If so, replace it
if (preg_match("/^(http:\/\/|www.)/i", $url))
{
$domain = preg_replace("/^(http:\/\/)*(www.)*/is", "", $url);
}
else
{
$domain = $url;
}
// Now all thats left is the domain and the extension
// Only return the needed first part without the extension
$domain = explode(".", $domain);
return $domain[0];
}
i have a script that keeps reloading every 2 seconds, i made a code to create a txt file for each user IP and write the user name $name inside it. my problem is that everytime my script reloads it will write the $name of the specific IP again with every reload.
the code is
$ip_file = "ips/".$ip.".txt";
$logip = fopen($ip_file,"a", 1);
$name = $name."\n";
fwrite($logip, $name);
fclose($logip);
return;
i need some way to verify if the name is already in the $ip_file and if it's there then not to write it again.
the idea behind this is to check if the same IP is used by more than one $name and then create a function to check all the $ip_file files for more than 1 $name and if so ban the violating $ip
thanks in advance
$ip_file = "ips/".$ip.".txt";
$names = file_get_contents($ip_file); //read names into string
if(false === strpos($names,$name)) { //write name if it's not there already
file_put_contents($ip_file,"$name\n",FILE_APPEND);
}
Is this what you need?
<?php
$ip_file = "ips/".$ip.".txt";
$name = $name."\n";
if (file_exists($ip_file)) {
$valueInFile = file_get_contents($ip_file, true);
if ($valueInFile == $name) {
//Do something
}
} else {
$logip = fopen($ip_file,"a", 1);
fwrite($logip, $name);
fclose($logip);
}
return;
?>
From:
http://php.net/manual/en/function.file-exists.php