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
}
}
Related
I am working on storing functionality of domains in laravel 5.3. Here user enter multiple domains in textarea one per line I want to validate each domain with right format should be create and other should be skipped and also count with correct format and bad format.
here is my code
$name = $request->input('domain_name');
$domains = preg_split('/[\r\n ,]+/', $name);
foreach ($domains as $domain) {
$data['domain'] = $domain;
$data['user_id'] = Auth::user()->id;
if (empty($request->input('domain_id'))) {
$domain = Domain::create($data);
}
}
Domain name with correct format should create and skip bad format and count both correct and incorrect formats.
Thanks for Help
Using preg_match and Regex:
if( ! preg_match("/^(?!-)(?:[a-zA-Zd-]{0,62}[a-zA-Zd].){1,126}(?!d+)[a-zA-Zd]{1,63}$/", $domain)) continue; // skip
or you can use this :
if(filter_var(gethostbyname($domain), FILTER_VALIDATE_IP))
{
return 'True';
}
I have to upload a website that uses Laravel.
The server I must use are using a reverse proxy and when I put the files i developped on my computer, I'm getting a DNS error.
I do not have access to the server configuration, I can only upload/download files on the website's server partition.
I searched to find a solution but anything I can find was sort of related to this question.
So, this is not Laravel version, but this can help you, I hope !
Here is some code I wrote in cakePHP 2.X because I have some issues with a reverse proxy too
Cache class is the one from cakePHP, it's very simple (60 sec expiration, automatically serialized data).
LogError function is a simple log function
The code is the following
// Constants
define('REVERSE_PROXY_ADDR' , 'r-proxy.internal-domain.com');
define('REVERSE_PROXY_CACHE', 'r-proxy');
// Cache Config
Cache::config(REVERSE_PROXY_CACHE, array(
'engine' => 'File',
'prefix' => REVERSE_PROXY_CACHE . '_',
'path' => CACHE . REVERSE_PROXY_CACHE . '/',
'serialize' => true,
'duration' => 60,
));
function clientIp()
{
// Originaly from CakePHP 2.X
// ------------------------------
if ( isset($_SERVER['HTTP_CLIENT_IP']) )
{
$ipaddr = $_SERVER['HTTP_CLIENT_IP'];
}
else
{
$ipaddr = $_SERVER['REMOTE_ADDR'];
}
if ( isset($_SERVER['HTTP_CLIENTADDRESS']) )
{
$tmpipaddr = $_SERVER['HTTP_CLIENTADDRESS'];
if ( !empty( $tmpipaddr ) )
{
$ipaddr = preg_replace('/(?:,.*)/', '', $tmpipaddr);
}
}
$ip = trim($ipaddr);
// ------------------------------
// Reverse proxy stuff
if ( defined('REVERSE_PROXY_ADDR') && defined('REVERSE_PROXY_CACHE') )
{
$xfor = preg_replace('/(?:,.*)/', '', $_SERVER['HTTP_X_FORWARDED_FOR']);
$list = Cache::read('iplist', REVERSE_PROXY_CACHE);
if ( $list === false )
{
$list = gethostbynamel(REVERSE_PROXY_ADDR);
Cache::write('iplist', $list, REVERSE_PROXY_CACHE);
}
// empty or unreadable
if ( empty( $list ) )
{
logError('Unable to gather reverse proxy ip list, or empty list');
logError('Type : ' . gettype($list));
logError('IP : ' . $ip . ' - X-FORWARDED-FOR : ' . $xfor);
return $ip;
}
// not array ?!?!
if ( !is_array($list) )
{
logError('Given list was not an array');
logError('Type : ' . gettype($list));
logError($list);
return $ip;
}
// if in array, give forwarded for header
if ( in_array($ip, $list, true) )
{
return $xfor;
}
}
return $ip;
}
Then you just have to call the clientIp(); function.
If you have a static IP Address for your reverse proxy, you can just set it manually in the code, but that's not a good practice. But you will not need to use cache, and it will simplify a lot the code.
If you use a dynamic reverse proxy, you will have to query it on its hostname like this (what I did in the posted code) :
gethostbynamel('reverse-proxy-addr') to get a list of possible rproxy IPs
OR
gethostbyname('reverse-proxy-addr') to get one IP for rproxy
In other case you just have to check that REMOTE_ADDR is in a list of IPs marked as Reverse-proxy IPs
Hope it helps !
Context:
I want to detect the two letter continent code of my user(s) to allow me to conditionally display an American or more general phone number.
E.g. If continent code is North America or South America, display North American phone number. Else, display general international phone number.
What I've tried:
A similar question on Stack Overflow was resolved using a light-weight function however in my case, the function did not output anything (i.e. blank).
The PHP manual lists the geoip_continent_code_by_name function of GEOIP extension however installation of this extension seems overkill and besides, I'm in no way familiar with command line installs for WHM/cPanel.
My question:
Is there an easier and lighter-weight method of detecting the two-letter continent code by IP?
You can use official API by MaxMind
https://maxmind.github.io/GeoIP2-php/
example of code
<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;
// This creates the Reader object, which should be reused across
// lookups.
$reader = new Reader('GeoLite2-Country.mmdb');
// Replace "city" with the appropriate method for your database, e.g.,
// "country".
$record = $reader->country('128.101.101.101');
echo ($record->continent->code);
You can use this function:
function get_continent_by_ip($ip = false) {
$code = false;
if (!$ip) {
$client = #$_SERVER['HTTP_CLIENT_IP'];
$forward = #$_SERVER['HTTP_X_FORWARDED_FOR'];
$remote = #$_SERVER['REMOTE_ADDR'];
if (filter_var($client, FILTER_VALIDATE_IP)) {
$ip = $client;
} elseif (filter_var($forward, FILTER_VALIDATE_IP)) {
$ip = $forward;
} else {
$ip = $remote;
}
}
$response = #json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip={$ip}"));
if ($response && isset($response->geoplugin_continentCode)) {
$code = $response->geoplugin_continentCode;
}
return $code;
}
It detects IP of user and returns code of continent
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
I have to two site one is my main site and otherone is for mobile site.This is the script i am using for redirecting the site on mobile when it is being used in mobile device. Now i want to ignore the mobile site redirection for iPad. I have used this script but its not ignoring iPad it still redirecting on mobile site on Ipad and i dont want this. Plz help.
<?php
function check_user_agent ( $type = NULL ) {
$user_agent = strtolower ( $_SERVER['HTTP_USER_AGENT'] );
if ( $type == 'bot' ) {
// matches popular bots
if ( preg_match ( "/googlebot|adsbot|yahooseeker|yahoobot|msnbot|watchmouse|pingdom\.com|feedfetcher-google/", $user_agent ) ) {
return true;
// watchmouse|pingdom\.com are "uptime services"
}
} else if ( $type == 'browser' ) {
// matches core browser types
if ( preg_match ( "/mozilla\/|opera\//", $user_agent ) ) {
return true;
}
} else if ( $type == 'mobile' ) {
// matches popular mobile devices that have small screens and/or touch inputs
// mobile devices have regional trends; some of these will have varying popularity in Europe, Asia, and America
// detailed demographics are unknown, and South America, the Pacific Islands, and Africa trends might not be represented, here
if( preg_match ( "/iPad/", $user_agent )) {
return false;
} else if ( preg_match ( "/phone|iphone|itouch|ipod|symbian|android|htc_|htc-|palmos|blackberry|opera mini|iemobile|windows ce|nokia|fennec|hiptop|kindle|mot |mot-|webos\/|samsung|sonyericsson|^sie-|nintendo/", $user_agent ) ) {
// these are the most common
return true;
} else if ( preg_match ( "/mobile|pda;|avantgo|eudoraweb|minimo|netfront|brew|teleca|lg;|lge |wap;| wap /", $user_agent ) ) {
// these are less common, and might not be worth checking
return true;
}
}
return false;
}
$ismobile = check_user_agent('mobile');
if($ismobile) {
header('Location:mobiles_site_url');
}
?>
You used strtolower() on the user agent string and the first line to check for the 'iPad' has an uppercase letter in it.
Try:
if( preg_match ( "/ipad/", $user_agent )) { // all lower case
....
}