Show different time when at different country - php

Want to ask.
How do I create a website that is able to show different time when at different country.
Example:
If user is using the website at Japan, it will show Japan's time.
While If user is using the website at Britain, it will show Britain's time.
Right now I am using this code:
<?php
date_default_timezone_set("Asia/Tokyo");
echo "Today's date is :";
$today = date("d/m/Y");
echo $today;
?>

You should do it on the client-side. I have read a forum once and they recommended it to be done in the client per se. Take what you think might help you from this javascript code example:
var now = new Date();
var utcString = now.toISOString().substring(0, 19);
var year = now.getFullYear();
var month = now.getMonth() + 1;
var day = now.getDate();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
var localDatetime = year + "-" +
(month < 10 ? "0" + month.toString() : month) + "-" +
(day < 10 ? "0" + day.toString() : day) + "T" +
(hour < 10 ? "0" + hour.toString() : hour) + ":" +
(minute < 10 ? "0" + minute.toString() : minute) +
utcString.substring(16, 19);
//var datetimeField = document.getElementById("myDatetimeField");
//datetimeField.value = localDatetime;
alert(localDatetime);

There is no function in php that can get user based timezone. But there is way around. First you have to grab user IP address, then you have make a call to a third party service to get geo information. Thus you can get user timezone.
The following function is fool-proof solution to get user IP using php so far. And credits goes to https://stackoverflow.com/a/38852532/7935051
<?php
function getClientIp() {
$ipAddress = '';
if (isset($_SERVER['HTTP_CLIENT_IP'])) {
$ipAddress = $_SERVER['HTTP_CLIENT_IP'];
} elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_X_FORWARDED'])) {
$ipAddress = $_SERVER['HTTP_X_FORWARDED'];
} elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
$ipAddress = $_SERVER['HTTP_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_FORWARDED'])) {
$ipAddress = $_SERVER['HTTP_FORWARDED'];
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
$ipAddress = $_SERVER['REMOTE_ADDR'];
} elseif (getenv('REMOTE_ADDR')) {
$ipAddress = getenv('REMOTE_ADDR');
} else {
$ipAddress = 'Unknown';
}
return $ipAddress;
}
Now you have to depend on the third party services to get geo information. This is very true for this type of jobs. There are several free services on internet, for example, geoPlugin. You may use it. See more details.
// Gets the client IP
$userIp = getClientIp();
$geoInfo = unserialize(file_get_contents("http://www.geoplugin.net/php.gp?ip={$userIp}"));
// Gets the timezone
$timezone = $geoInfo['geoplugin_timezone'];
// Sets user timezone, otherwise uses default
if ($timezone) {
date_default_timezone_set($timezone);
} else {
date_default_timezone_set('Asia/Tokyo');
}
echo "Today's date is :";
$today = date("d/m/Y");
echo $today;
BTW you may debug $geoInfo variables to get more information

Related

Calculate IP Between IP range PHP

How do i calculate between Ip Addresses.
for Example:
$ip_low_range = '91.0.0.0';
$ip_max_range = '91.23.255.255';
$user_ip = '91.1.0.0';
in_range($user_ip , $ip_low_range , $ip_max_range,);
in_range() - is the function that i'm looking for.
Thanks!
You could use ip2long:
$ip_low_range = ip2long('91.0.0.0');
$ip_max_range = ip2long('91.23.255.255');
$user_ip = ip2long('91.1.0.0');
if ($user_ip >= $ip_low_range && $user_ip <= $ip_max_range) {
echo "in range";
}

HTTP Referrer through Age Gate

I have an age gate set up on my site, so that users under 17 can't enter the site, but I want people, who have bookmarked a specific link to be able to go to that link after passing through the age gate:
Here is my age gate code:
<?php
session_start();
if(isset($_SESSION['legal'])) { # Check to see if session has already been set
$url = ($_SESSION['legal'] == 'yes') ? 'index.php' : 'message.php';
header ('Location: ' .$url);
}
// If visitor hasn't gone through the age gate - Age Gate function and Set Session//
if(isset($_POST['checkage'])) {
$day = ctype_digit($_POST['day']) ? $_POST['day'] : '';
$month = ctype_digit($_POST['month']) ? $_POST['month'] : '';
$year = ctype_digit($_POST['year']) ? $_POST['year'] : '';
$birthstamp = mktime(0, 0, 0, $month, $day, $year);
$diff = time() - $birthstamp;
$age_years = floor($diff / 31556926);
if($age_years >= 18) {
$_SESSION['legal'] = 'yes';
$url = 'index.php';
} else {
$_SESSION['legal'] = 'no';
// If failed the Age Gate go to specific page
$url = 'message.php';
}
header ('Location: ' .$url);
}
?>
What can I add to this code so that if I wanted to go to domain/page.php or domain/subdirectory/ -- the Age Gate will take me there after I pass it? (I know I have to use HTTP Referrer, but I can't figure out how to include it).
Edit to Add : I know that sometimes Browsers will not keep/send the HTTP Referrer, so I will need a solution for those who don't pass that value.
EDIT : AGE Calculation based on the form submission -
$day = ctype_digit($_POST['day']) ? $_POST['day'] : '';
$month = ctype_digit($_POST['month']) ? $_POST['month'] : '';
$year = ctype_digit($_POST['year']) ? $_POST['year'] : '';
$birthstamp = mktime(0, 0, 0, $month, $day, $year);
$diff = time() - $birthstamp;
$age_years = floor($diff / 31556926);
I'd setup this the other way around: have each page set a $_SESSION variable to indicate where to go:
if (!isset($_SESSION['legal']) || $_SESSION['legal'] == 'no') {
$_SESSION['target'] = $_SERVER['PHP_SELF'];
header('Location: message.php');
return;
}
// continue script execution...
And in your message.php:
$isLegal = check_age(); // your age checking logic
if ($isLegal && isset($_SESSION['target'])) {
header('Location: ' . $_SESSION['target']);
} else if ($isLegal) {
header('Location: index.php');
} else {
// setup message.php with a validation failed message
}
Mind, this is just one of the possible variations, but I'd suggest not relying on user data such as the referrer (some browser extensions even explicitly unset/modify that).

Getting list IPs from CIDR notation in PHP

Is there a way (or function/class) to get the list of IP addresses from a CIDR notation?
For example, I have 73.35.143.32/27 CIDR and want to get the list of all IP's in this notation. Any suggestions?
Thank you.
I'll edit the aforementioned class to contain a method for that. Here is the code I came up with that might help you until then.
function cidrToRange($cidr) {
$range = array();
$cidr = explode('/', $cidr);
$range[0] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1]))));
$range[1] = long2ip((ip2long($range[0])) + pow(2, (32 - (int)$cidr[1])) - 1);
return $range;
}
var_dump(cidrToRange("73.35.143.32/27"));
//////////////////OUTPUT////////////////////////
// array(2) {
// [0]=>
// string(12) "73.35.143.32"
// [1]=>
// string(12) "73.35.143.63"
// }
/////////////////////////////////////////////////
Returns the low end of the ip range as the first entry in the array, then returns the high end as the second entry.
Well, it's a bitmask - 73.35.143.32/27 means that 27 bits are the network mask, and the rest is available for assigning to the nodes in the network:
73.35.143.32
in binary is this (dots shown for legibility):
01001001.00100011.10001111.00100000
The netmask is 27 bits:
11111111.11111111.11111111.11100000
So you can just AND them together and get this:
01001001.00100011.10001111.001 00000
network prefix (27 bits) | node address (5 bits)
From here, you can just enumerate all the combinations in the node address (00000 is 0, 11111 is 31, so a simple loop is enough), and you'll have all the available hosts.
Converting this pseudocode to PHP is left as an exercise to the reader ;)
Oh, and the obligatory deprecation warning: IPv4 is now full, consider also IPv6.
Here is one fast 64bits function to do it, please comment the return line you don't need. Accepting any valid Ipv4 with or without valid CIDR Routing Prefix for example 63.161.156.0/24 or 63.161.156.0
<?php
function cidr2range($ipv4){
if ($ip=strpos($ipv4,'/'))
{$n_ip=(1<<(32-substr($ipv4,1+$ip)))-1; $ip_dec=ip2long(substr($ipv4,0,$ip)); }
else
{$n_ip=0; $ip_dec=ip2long($ipv4); }
$ip_min=$ip_dec&~$n_ip;
$ip_max=$ip_min+$n_ip;
#Array(2) of Decimal Values Range
return [$ip_min,$ip_max];
#Array(2) of Ipv4 Human Readable Range
return [long2ip($ip_min),long2ip($ip_max)];
#Array(2) of Ipv4 and Subnet Range
return [long2ip($ip_min),long2ip(~$n_ip)];
#Array(2) of Ipv4 and Wildcard Bits
return [long2ip($ip_min),long2ip($n_ip)];
#Integer Number of Ipv4 in Range
return ++$n_ip;
}
To run fast the function don't check input but formally it should be a string matching the following regex
#^(?:((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))(?:/((?:(?:0)|(?:3[0-2])|(?:[1-2]?[0-9]))))?)$#
If you want to verify the input before using the function
<?php
if (is_string($ipv4) && preg_match('#^(?:((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))(?:/((?:(?:0)|(?:3[0-2])|(?:[1-2]?[0-9]))))?)$#',$ipv4))
{
#This is a valid ipv4 with or without CIDR Routing Prefix
$result=cidr2range($ipv4);
print_r($result);
}
To get the full range as an array for a given IP (with or without CIDR Routing Prefix) you can use the following code but be carefull because for example 25.25.25.25/16 return an array with 65536 elements and you can easily run out of memory using a smaller Routing Prefix
<?php
$result=cidr2range($ipv4);
for($ip_dec=$result[0];$ip_dec<=$result[1];$ip_dec++)
$full_range[$ip_dec]=long2ip($ip_dec);
print_r($full_range);
To fast check if a given ipv4 is matching a given CIDR you can do it inline like in this example
<?php
$given_cidr='55.55.55.0/24';
$given_ipv4='55.55.55.55';
if(($range=cidr2range($given_cidr)) &&
($check=ip2long($given_ipv4))!==false &&
$check>=$range[0] && $check<=$range[1])
{
echo 'Yes, '.$given_ipv4.' is included in '.$given_cidr;
}
else
{
echo 'No, '.$given_ipv4.' is not included in '.$given_cidr;
}
To fast check if a given ipv4 is matching a given array of IP (with or without CIDR Routing Prefix)
<?php
#This code is checking if a given ip belongs to googlebot
$given_ipv4='74.125.61.208';
$given_cidr_array=['108.59.93.43/32','108.59.93.40/31','108.59.93.44/30','108.59.93.32/29','108.59.93.48/28','108.59.93.0/27','108.59.93.64/26','108.59.93.192/26','108.59.92.192/27','108.59.92.128/26','108.59.92.96/27','108.59.92.0/27','108.59.94.208/29','108.59.94.192/28','108.59.94.240/28','108.59.94.128/26','108.59.94.16/29','108.59.94.0/28','108.59.94.32/27','108.59.94.64/26','108.59.95.0/24','108.59.88.0/22','108.59.81.0/27','108.59.80.0/24','108.59.82.0/23','108.59.84.0/22','108.170.217.128/28','108.170.217.160/27','108.170.217.192/26','108.170.217.0/25','108.170.216.0/24','108.170.218.0/23','108.170.220.0/22','108.170.208.0/21','108.170.192.0/20','108.170.224.0/19','108.177.0.0/17','104.132.0.0/14','104.154.0.0/15','104.196.0.0/14','107.167.160.0/19','107.178.192.0/18','125.17.82.112/30','125.16.7.72/30','74.125.0.0/16','72.14.192.0/18','77.109.131.208/28','77.67.50.32/27','66.102.0.0/20','66.227.77.144/29','66.249.64.0/19','67.148.177.136/29','64.124.98.104/29','64.71.148.240/29','64.68.64.64/26','64.68.80.0/20','64.41.221.192/28','64.41.146.208/28','64.9.224.0/19','64.233.160.0/19','65.171.1.144/28','65.170.13.0/28','65.167.144.64/28','65.220.13.0/24','65.216.183.0/24','70.32.132.0/23','70.32.128.0/22','70.32.136.0/21','70.32.144.0/20','85.182.250.128/26','85.182.250.0/25','80.239.168.192/26','80.149.20.0/25','61.246.224.136/30','61.246.190.124/30','63.237.119.112/29','63.226.245.56/29','63.158.137.224/29','63.166.17.128/25','63.161.156.0/24','63.88.22.0/23','41.206.188.128/26','12.234.149.240/29','12.216.80.0/24','8.34.217.24/29','8.34.217.0/28','8.34.217.32/27','8.34.217.64/26','8.34.217.128/25','8.34.216.0/24','8.34.218.0/23','8.34.220.0/22','8.34.208.128/29','8.34.208.144/28','8.34.208.160/27','8.34.208.192/26','8.34.208.0/25','8.34.209.0/24','8.34.210.0/23','8.34.212.0/22','8.35.195.128/28','8.35.195.160/27','8.35.195.192/26','8.35.195.0/25','8.35.194.0/24','8.35.192.0/23','8.35.196.0/22','8.35.200.0/21','8.8.8.0/24','8.8.4.0/24','8.6.48.0/21','4.3.2.0/24','23.236.48.0/20','23.251.128.0/19','216.239.32.0/19','216.252.220.0/22','216.136.145.128/27','216.33.229.160/29','216.33.229.144/29','216.34.7.176/28','216.58.192.0/19','216.109.75.80/28','216.74.130.48/28','216.74.153.0/27','217.118.234.96/28','208.46.199.160/29','208.44.48.240/29','208.21.209.0/28','208.184.125.240/28','209.185.108.128/25','209.85.128.0/17','213.200.103.128/26','213.200.99.192/26','213.155.151.128/26','199.192.112.224/29','199.192.112.192/27','199.192.112.128/26','199.192.112.0/25','199.192.113.176/28','199.192.113.128/27','199.192.113.192/26','199.192.113.0/25','199.192.115.80/28','199.192.115.96/27','199.192.115.0/28','199.192.115.128/25','199.192.114.192/26','199.192.114.0/25','199.223.232.0/21','198.108.100.192/28','195.16.45.144/29','192.104.160.0/23','192.158.28.0/22','192.178.0.0/15','206.160.135.240/28','207.223.160.0/20','203.222.167.144/28','173.255.125.72/29','173.255.125.80/28','173.255.125.96/27','173.255.125.0/27','173.255.125.128/25','173.255.124.240/29','173.255.124.232/29','173.255.124.192/27','173.255.124.128/29','173.255.124.144/28','173.255.124.160/27','173.255.124.48/29','173.255.124.32/28','173.255.124.0/27','173.255.124.64/26','173.255.126.0/23','173.255.122.128/26','173.255.122.64/26','173.255.123.0/24','173.255.121.128/26','173.255.121.0/25','173.255.120.0/24','173.255.117.32/27','173.255.117.64/26','173.255.117.128/25','173.255.116.192/27','173.255.116.128/26','173.255.116.0/25','173.255.118.0/23','173.255.112.0/22','173.194.0.0/16','172.102.8.0/21','172.253.0.0/16','172.217.0.0/16','162.216.148.0/22','162.222.176.0/21','180.87.33.64/26','128.177.109.0/26','128.177.119.128/25','128.177.163.0/25','130.211.0.0/16','142.250.0.0/15','146.148.0.0/17'];
echo '<pre>';
$in_range=false;
if (($given_ipv4_dec=ip2long($given_ipv4))!==false)
{
foreach($given_cidr_array as $given_cidr){
if(($range=cidr2range($given_cidr)) &&
$given_ipv4_dec>=$range[0] && $given_ipv4_dec<=$range[1])
{
$in_range=true;
echo $given_ipv4.' matched '.$given_cidr.' ('.join(array_map('long2ip',$range),' - ').")\n";
}
}
}
echo $given_ipv4.' is probably'.($in_range?'':' not').' a Googlebot IP';
hope that these few lines have helped you…
There is small fix - when someone place ip prefix like: 127.0.0.15/26 this function returns bad last IP adress. In this function is at line 4 (starts: $range[1]...) changed $cidr[0] to $range[0] - now its return last IP address good for every IP in range.
function cidrToRange($cidr) {
$range = array();
$cidr = explode('/', $cidr);
$range[0] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1]))));
$range[1] = long2ip((ip2long($range[0])) + pow(2, (32 - (int)$cidr[1])) - 1);
return $range;
}
var_dump(cidrToRange("127.0.0.15/26"));
Before fix:
array(2) {
[0]=>
string(9) "127.0.0.0"
[1]=>
string(10) "127.0.0.78"
}
string(41) "127.0.0.15/26 >> 2130706432 -> 2130706510"
After fix:
array(2) {
[0]=>
string(9) "127.0.0.0"
[1]=>
string(10) "127.0.0.63"
}
string(41) "127.0.0.15/26 >> 2130706432 -> 2130706495"
Highly recommend this PHP Lib:
https://github.com/S1lentium/IPTools
It can manipulate network easily with many functions.
e.g. Iterate over Network IP adresses:
$network = Network::parse('192.168.1.0/24');
foreach($network as $ip) {
echo (string)$ip . PHP_EOL;
}
// output:
192.168.1.0
...
192.168.1.255
I come up with a better idea
$ip_from= long2ip(ip2long($ip)& (-1<<(32-$net_mask)));
$ip_to= long2ip(ip2long($ip)| (~(-1<<(32-$net_mask))));
P.S:$ip is a ipv4 address like 60.12.34.5;$net_mask is a int net mask like 25;
it's very fast because of the bit shift operation
this returns an array of ips:
function get_list_ip($ip_addr_cidr){
$ip_arr = explode("/", $ip_addr_cidr);
$bin = "";
for($i=1;$i<=32;$i++) {
$bin .= $ip_arr[1] >= $i ? '1' : '0';
}
$ip_arr[1] = bindec($bin);
$ip = ip2long($ip_arr[0]);
$nm = $ip_arr[1];
$nw = ($ip & $nm);
$bc = $nw | ~$nm;
$bc_long = ip2long(long2ip($bc));
for($zm=1;($nw + $zm)<=($bc_long - 1);$zm++)
{
$ret[]=long2ip($nw + $zm);
}
return $ret;
}
Extension to #jonavon 's answer. If you need flat list of IPs. You can convert his function like below.
function cidrToRange($value) {
$range = array();
$split = explode('/', $value);
if (!empty($split[0]) && is_scalar($split[1]) && filter_var($split[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$rangeStart = ip2long($split[0]) & ((-1 << (32 - (int)$split[1])));
$rangeEnd = ip2long($split[0]) + pow(2, (32 - (int)$split[1])) - 1;
for ($i = $rangeStart; $i <= $rangeEnd; $i++) {
$range[] = long2ip($i);
}
return $range;
} else {
return $value;
}
}
I don't believe this class will return a list of IPs, but it does provide some useful methods for working with CIDR blocks.
I previously wrote an entire Class which handled this task pretty well (for another Language), and thanks to PHP's ip2long(...) method, we don't need to calculate manually in PHP.
But my Unit-Test data can be used to test any of the other answers:
<?php
// Below has "CIDR = Minimum ... Maximum" format.
$validRangeMap = [
'0.0.0.0/1=0.0.0.0...127.255.255.255',
'128.0.0.0/2=128.0.0.0...191.255.255.255',
'192.0.0.0/9=192.0.0.0...192.127.255.255',
'192.128.0.0/11=192.128.0.0...192.159.255.255',
'192.160.0.0/13=192.160.0.0...192.167.255.255',
'192.168.0.0/19=192.168.0.0...192.168.31.255',
'192.168.32.0/21=192.168.32.0...192.168.39.255',
'192.168.40.0/23=192.168.40.0...192.168.41.255',
'192.168.42.0/23=192.168.42.0...192.168.43.255',
'192.168.44.0/22=192.168.44.0...192.168.47.255',
'192.168.48.0/20=192.168.48.0...192.168.63.255',
'192.168.64.0/18=192.168.64.0...192.168.127.255',
'192.168.128.0/17=192.168.128.0...192.168.255.255',
'192.169.0.0/16=192.169.0.0...192.169.255.255',
'192.170.0.0/15=192.170.0.0...192.171.255.255',
'192.172.0.0/14=192.172.0.0...192.175.255.255',
'192.176.0.0/12=192.176.0.0...192.191.255.255',
'192.192.0.0/10=192.192.0.0...192.255.255.255',
'193.0.0.0/8=193.0.0.0...193.255.255.255',
'194.0.0.0/7=194.0.0.0...195.255.255.255',
'196.0.0.0/6=196.0.0.0...199.255.255.255',
'200.0.0.0/5=200.0.0.0...207.255.255.255',
'208.0.0.0/4=208.0.0.0...223.255.255.255',
'224.0.0.0/4=224.0.0.0...239.255.255.255',
'240.0.0.0/5=240.0.0.0...247.255.255.255',
'248.0.0.0/6=248.0.0.0...251.255.255.255',
'252.0.0.0/7=252.0.0.0...253.255.255.255',
'254.0.0.0/8=254.0.0.0...254.255.255.255',
'255.0.0.0/9=255.0.0.0...255.127.255.255',
'255.128.0.0/10=255.128.0.0...255.191.255.255',
'255.192.0.0/11=255.192.0.0...255.223.255.255',
'255.224.0.0/12=255.224.0.0...255.239.255.255',
'255.240.0.0/13=255.240.0.0...255.247.255.255',
'255.248.0.0/14=255.248.0.0...255.251.255.255',
'255.252.0.0/15=255.252.0.0...255.253.255.255',
'255.254.0.0/16=255.254.0.0...255.254.255.255',
'255.255.0.0/17=255.255.0.0...255.255.127.255',
'255.255.128.0/18=255.255.128.0...255.255.191.255',
'255.255.192.0/19=255.255.192.0...255.255.223.255',
'255.255.224.0/20=255.255.224.0...255.255.239.255',
'255.255.240.0/21=255.255.240.0...255.255.247.255',
'255.255.248.0/22=255.255.248.0...255.255.251.255',
'255.255.252.0/23=255.255.252.0...255.255.253.255',
'255.255.254.0/24=255.255.254.0...255.255.254.255',
'255.255.255.0/25=255.255.255.0...255.255.255.127',
'255.255.255.128/26=255.255.255.128...255.255.255.191',
'255.255.255.192/27=255.255.255.192...255.255.255.223',
'255.255.255.224/28=255.255.255.224...255.255.255.239',
'255.255.255.240/29=255.255.255.240...255.255.255.247',
'255.255.255.248/30=255.255.255.248...255.255.255.251',
'255.255.255.252/31=255.255.255.252...255.255.255.253',
'255.255.255.254/32=255.255.255.254...255.255.255.254',
];
Example
We can test Jonavon's answer, like:
foreach ($validRangeMap as $entry) {
$expected = preg_split('/(=|(\.\.\.))+/', $entry);
$actual = cidrToRange($expected[0]);
if ($actual[0] !== $expected[1]) {
echo "Test-Failed! '$actual[0]' should be equal '$expected[1]' <br>" . PHP_EOL;
} else if ($actual[1] !== $expected[2]) {
echo "Test-Failed! '$actual[1]' should be equal '$expected[2]' <br>" . PHP_EOL;
} else {
echo "Tested '$expected[0]' CIDR <br>" . PHP_EOL;
}
}
function cidrToRange($cidr) {
$range = array();
$cidr = explode('/', $cidr);
$range[0] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1]))));
$range[1] = long2ip((ip2long($range[0])) + pow(2, (32 - (int)$cidr[1])) - 1);
return $range;
}
Note that it passed the tests.
The utility cidrl will do this:
$ cidrl 73.35.143.32/27
73.35.143.32
73.35.143.33
73.35.143.34
...
73.35.143.63
The PHP function cidrl() iterates over each IP address in a CIDR block using an anonymous function:
cidrl('194.168.0.1/28', $error_code, function($address) {
print "$address\n";
});
Or, as an array:
$addresses = cidrl('194.168.0.1/28', $error_code);
Can be installed from Packagist emden-norfolk/cidrl with Composer:
composer require emden-norfolk/cidrl
(Note: This package is no longer supported in favour of the cidrl command mentioned in my other answer.)
Hej. I also needed this function and I edit 1 other to return me list of all IP addresses from range.
This will return list of IP addresses from CIDR Notation. Enjoy it ;)
<?php
$ip_addr_cidr = "192.256.0.0/16";
$ip_arr = explode('/', $ip_addr_cidr);
$bin = '';
for($i=1;$i<=32;$i++) {
$bin .= $ip_arr[1] >= $i ? '1' : '0';
}
$ip_arr[1] = bindec($bin);
$ip = ip2long($ip_arr[0]);
$nm = ip2long($ip_arr[1]);
$nw = ($ip & $nm);
$bc = $nw | (~$nm);
echo "Number of Hosts: " . ($bc - $nw - 1) . "<br/>";
echo "Host Range: " . long2ip($nw + 1) . " -> " . long2ip($bc - 1) . "<br/>". "<br/>";
for($zm=1;($nw + $zm)<=($bc - 1);$zm++)
{
echo long2ip($nw + $zm). "<br/>";
}
?>
Fixed version of Kosmonaft script:
function get_list_ip($ip_addr_cidr){
$ip_arr = explode("/", $ip_addr_cidr);
$bin = "";
for($i=1;$i<=32;$i++) {
$bin .= $ip_arr[1] >= $i ? '1' : '0';
}
$ip_arr[1] = bindec($bin);
$ip = ip2long($ip_arr[0]);
$nm = $ip_arr[1];
$nw = ($ip & $nm);
$bc = $nw | ~$nm;
$bc_long = ip2long(long2ip($bc));
echo "Number of Hosts: " . ($bc_long - $nw - 1) . "<br/>";
echo "Host Range: " . long2ip($nw + 1) . " -> " . long2ip($bc - 1) . "<br/>". "<br/>";
for($zm=1;($nw + $zm)<=($bc_long - 1);$zm++)
{
echo long2ip($nw + $zm). "<br/>";
}
}
I had some problems with the previous versions, various PHP errors like undefined offset etc.
I found what I think is a better way to do it without the errors as detailed below.
This takes IPV4 CIDR notation IP addresses and can be used to get the start/end IP addresses of the CIDR range or count the total number of IP addresses in a database of IP addresses.
$count = 0;
$result = $sia_db_con->query("SELECT `ip_address` FROM `ip4` WHERE `ip_ban_active`='True' ORDER BY ip4.added ASC");
while ($row = $result->fetch_array()) {
$pos = strpos($row[0], "/");
$ip_arr = [0 => substr($row[0], 0, $pos), 1 => substr($row[0], $pos+1)];
$start = cidr2ip($ip_arr)[0];
$end = cidr2ip($ip_arr)[1];
$count = $count + (ip2long($end) - ip2long($start)) + 1;
}
unset($result, $row, $pos, $ip_arr, $start, $end, $range);
function cidr2ip($cidr) {
$start = ip2long($cidr[0]);
$nm = $cidr[1];
$num = pow(2, 32 - $nm);
$end = $start + $num - 1;
$range = [0 => $cidr[0], 1 => long2ip($end)];
unset($start, $nm, $num, $end);
return $range;
}
The secret here is the way in which I create the $ip_arr variable. Rather than using PHP explode, I set the array dimensions manually for each IP address. This is of course a database version of the code and cycles through all IP addresses in the database which meet the search criteria.

how to restrict a page to only a specified ip range in php

im looking for a way to restrict my administration page to only my own ip range
concider my ip range is 215.67..
so in php i will begin with this :
$myip = "215.67.*.*";
$myip = explode(".", $my_ip);
$userip = getenv("REMOTE_ADDR") ;
$userip = explode(".", $userip);
if ($myip[0] == $userip[0] AND $myip[1] == $userip[1] ) {
//Contunue admin
}
is there any better and more professional way to do it ?
<?php
function in_ip_range($ip_one, $ip_two=false){
if($ip_two===false){
if($ip_one==$_SERVER['REMOTE_ADDR']){
$ip=true;
}else{
$ip=false;
}
}else{
if(ip2long($ip_one)<=ip2long($_SERVER['REMOTE_ADDR']) && ip2long($ip_two)>=ip2long($_SERVER['REMOTE_ADDR'])){
$ip=true;
}else{
$ip=false;
}
}
return $ip;
}
//usage
echo in_ip_range('192.168.0.0','192.168.1.254');
?>
Taken from http://www.php.net/manual/en/function.ip2long.php#81030

Display Google Keywords that brought a user to the site

I am looking to display something like:
Hello, you've reached this site by looking for [google keyword(s)]
I'm pretty sure I've seen this done before but I am having troubles figuring out how to grab the keywords that were used to lead a user to my site. Anyone know the answer?
You need to get the referring URL and then strip out everything for the "q" query string. This will give you the query that was used to get you to your page.
Using the referrer (http://www.netmechanic.com/news/vol4/javascript_no14.htm) you can find where the user comes from. Then it's just a matter of parsing it correctly.
I saw this script :
function getkeywords() {
var x = document.referrer;
var lastparturl = 0;
if (x.search(/google/) != -1) {
lastparturl = x.indexOf("&btnG=Google+Search");
x = x.slice(38,lastparturl);
x = x.concat("via google");
}
else if (x.search(/yahoo/) != -1) {
lastparturl = x.indexOf("&ei=UTF-8&iscqry=&fr=sfp");
x = x.slice(63,lastparturl);
x = x.concat("via yahoo");
}
else if (x.search(/ask.com/) != -1) {
lastparturl = x.indexOf("&search=search&qsrc=0&o=0&l=dir");
x = x.slice(25,lastparturl);
x = x.concat("via ask");
}
else if (x.search(/dogpile/) != -1) {
lastparturl = x.indexOf("/1/417/TopNavigation/Relevance/iq=true/zoom=off/_iceUrlFlag=7?_IceUrl=true");
x = x.slice(46,lastparturl);
x = x.concat("via dogpile");
}
else if (x.search(/altavista/) != -1) {
lastparturl = x.indexOf("&kgs=1&kls=0");
x = x.slice(48,lastparturl);
x = x.concat("via altavista");
}
else {
x = "no keywords available";
}
x = x.replace(/+/, " ");
return x;
}
Here http://www.webmonkey.com/codelibrary/Get_Referrer_Keywords
I'm not sure if it works perfectly, but it worked OK when I reached their website through google.
I also saw that some scripts that you can download do that, for instance: http://webscripts.softpedia.com/script/Search-Engines/Keyword-Grabber-45299.html
Again, this will need to be tested.

Categories