Display different content depending on Referrer - php

Hey I am trying to display a different phone number for visitors my website from my Google adwords campaign.
The code below works without the else statement (so if I click through to the page from Google it will display a message, and if I visit the site regularly it does not). When I added the else statement it outputs both numbers. Thank you
<?php
// The domain list.
$domains = Array('googleadservices.com', 'google.com');
$url_info = parse_url($_SERVER['HTTP_REFERER']);
if (isset($url_info['host'])) {
foreach($domains as $domain) {
if (substr($url_info['host'], -strlen($domain)) == $domain) {
// GOOGLE NUMBER HERE
echo ('1234');
}
// REGULAR NUMBER HERE
else {
echo ('12345');
}
}
}
?>

Your logic is slightly skewed; you're checking to see if the URL from parse_url matches the domains in your array; but you're running through the whole array each time. So you get both a match and a non-match, because google.com matches one entry but not the other.
I'd suggest making your domains array into an associative array:
$domains = Array('googleadservices.com' => '1234',
'google.com' => '12345' );
Then you just need to check once:
if (isset($url_info['host'])) {
if (isset($domains[$url_info['host']])) {
echo $domains[$url_info['host']];
}
}
I've not tested this, but it should be enough for you to see the logic.
(I've also removed the substr check - you may need to put that back in, to ensure that you're getting the exact string that you need to look for)

Related

I don't want to display ads to Facebook, Twitter Visitors

I am now using this code for facebook. "https" is active and wordpress site.
<?php
$ref = $_SERVER['HTTP_REFERER'];
if (strpos($ref, 'facebook.com') != false) {
?>
DON'T SHOW ADS
<?php } else { ?>
SHOW ADS
<?php } ?>
This code works for facebook. I wanted to add twitter, but when I add twitter it doesn't work at all. I tried this.
if (strpos($ref, 'facebook.com', 'twitter.com', 't.co') != false) {
It didn't work that way. If else query or "false" is correct? How can I do it in the simplest way? If the visitor comes from Facebook, Twitter, I don't want to show ads. thanks
strpos() does not check multiple "needles" to look for. You can store them in an array
and iterate over each one individually though:
<?php
$ref = $_SERVER['HTTP_REFERER'];
$sitesWithAdsHidden = [
'facebook.com',
'twitter.com',
't.co',
];
$isHiddenSite = false;
foreach ($sitesWithAdsHidden as $site) {
if (strpos($ref, $site) !== false) {
$isHiddenSite = true;
break;
}
}
if ($isHiddenSite) {
?>
DON'T SHOW ADS
<?php } else { ?>
SHOW ADS
<?php } ?>
Note that I also changed the strpos comparison to !== because a non-strict check could lead to evaluating to false if the position is actually 0 (the start of the string).
First and foremost, directly from Wikipedia:
"The referrer field is an optional part of the HTTP request sent by the web browser to the web server."
Therefore, you should always check that the Http Referer exists in the request. You can achieve this by using !empty() or isset(), however, for future maintainability, you can also use array_diff and array_keys.
You can then also achieve this without having to iterate over an array using preg_match.
if(!array_diff(['HTTP_REFERER'], array_keys($_SERVER)))
if(preg_match('/facebook|twitter/', $_SERVER['HTTP_REFERER']))
// todo: disable adverts
You could also use the null cascading operator to reduce this to one line. Do this if you have no further checks to make from the $_SERVER global variable.
if(preg_match('/facebook|twitter/', $_SERVER['HTTP_REFERER'] ?? ''))
// todo: disable adverts

Validate parts of URLs with PHP

I'm trying to check against an array of URL's with PHP, but one of the URL's will have some random strings in front of it (generated sub domain).
This is what I have so far:
<?php
$urls = array(
'127.0.0.1',
'develop.domain.com'
);
?>
<?php if (in_array($_SERVER['SERVER_NAME'], $urls)) : ?>
//do the thing
<?php endif; ?>
The only thing is that the develop.domain.com will have something in front of it. For example namething.develop.domain.com.
Is there a way to check for a wildcard in the array of URL's so that it can check for the 127.0.0.1 and and matches for develop.domain.com?
Simplest way is to go all regex like this
// Array of allowed url patterns
$urls = array(
'/^127.0.0.1$/',
'/^(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*(develop.domain.com)$/i'
);
// For each of the url patterns in $urls,
// try to match the $_SERVER['SERVER_NAME']
// against
foreach ($urls as $url) {
if (preg_match($url, $_SERVER['SERVER_NAME'])) {
// Match found. Do something
// Break from loop since $_SERVER['SERVER_NAME']
// a pattern
break;
}
}
Assuming that URL will use one word in sub-domain like you mentioned in your question.
If URL consists of more than one word then the following code needs to be modified as per expected word in sub-domain.
<?php
// Supported URLs array
$urls = array(
'127.0.0.1',
'develop.domain.com'
);
// Server name
//$_server_name = $_SERVER['SERVER_NAME'];
$_server_name = 'namething.develop.domain.com';
// Check if current server name contains more than 2 "." which means it has sub-subdomain
if(substr_count($_server_name, '.') > 2) {
// Fetch sub-string from current server name starting after first "." position till end and update it to current server name variable
$_server_name = substr($_server_name, strpos($_server_name, '.')+1, strlen($_server_name));
}
// Check if updated/filterd server name exists in our allowed URLs array
if (in_array($_server_name, $urls)){
// do something
echo $_server_name;
}
?>
Output:
PASS domain.develop.domain.com
PASS namething.develop.domain.com
FAIL subsubdomain.domain.develop.domain.com
FAIL namething1.namething2.develop.domain.com

Using file_get_contents for multiple sites with same content

I want to grab a code from some websites (all of them have the same content but some of them have downtime).
So i want to make a code that checks the first site and if the code was found show it, if not check the second site etc.
The code that i have is this:
$website1 = file_get_contents("http://exemplesite1.com");
preg_match("' src=\"(.*?)\" type='si", $website1, $body);
$decoded_url = $body[1];
if ( $decoded_url == "" ) {
$website2 = file_get_contents("http://exemplesite2.com");
preg_match("' src=\"(.*?)\" type='si", $website2, $body);
$decoded_url2 = $body[1];
} elseif ...
Here i'm blocked, i have like 6 sites, i want to do this untill it finds the code i need.
Put the websites in an array, and loop through that. Assuming you only need the first one, you can exit the loop upon finding a match. Something like this:
$websites = ['http://exemplesite1.com', 'http://exemplesite2.com', ...];
foreach($websites as $website) {
preg_match("' src=\"(.*?)\" type='si", $website, $body);
$decoded_url = $body[1];
if (! empty($decoded_url)) //found proper match
break;
}

PHP Auto-correcting URLs

I dont wan't reinvent wheel, but i couldnt find any library that would do this perfectly.
In my script users can save URLs, i want when they give me list like:
google.com
www.msn.com
http://bing.com/
and so on...
I want to be able to save in database in "correct format".
Thing i do is I check is it there protocol, and if it's not present i add it and then validate URL against RegExp.
For PHP parse_url any URL that contains protocol is valid, so it didnt help a lot.
How guys you are doing this, do you have some idea you would like to share with me?
Edit:
I want to filter out invalid URLs from user input (list of URLs). And more important, to try auto correct URLs that are invalid (ex. doesn't contains protocol). Ones user enter list, it should be validated immediately (no time to open URLs to check those they really exist).
It would be great to extract parts from URL, like parse_url do, but problem with parse_url is, it doesn't work well with invalid URLs. I tried to parse URL with it, and for parts that are missing (and are required) to add default ones (ex. no protocol, add http). But parse_url for "google.com" wont return "google.com" as hostname but as path.
This looks like really common problem to me, but i could not find available solution on internet (found some libraries that will standardize URL, but they wont fix URL if it is invalid).
Is there some "smart" solution to this, or I should stick with my current:
Find first occurrence of :// and validate if it's text before is valid protocol, and add protocol if missing
Found next occurrence of / and validate is hostname is in valid format
For good measure validate once more via RegExp whole URL
I just have feeling I will reject some valid URLs with this, and for me is better to have false positive, that false negative.
I had the same problem with parse_url as OP, this is my quick and dirty solution to auto-correct urls(keep in mind that the code in no way are perfect or cover all cases):
Results:
http:/wwww.example.com/lorum.html => http://www.example.com/lorum.html
gopher:/ww.example.com => gopher://www.example.com
http:/www3.example.com/?q=asd&f=#asd =>http://www3.example.com/?q=asd&f=#asd
asd://.example.com/folder/folder/ =>http://example.com/folder/folder/
.example.com/ => http://example.com/
example.com =>http://example.com
subdomain.example.com => http://subdomain.example.com
function url_parser($url) {
// multiple /// messes up parse_url, replace 2+ with 2
$url = preg_replace('/(\/{2,})/','//',$url);
$parse_url = parse_url($url);
if(empty($parse_url["scheme"])) {
$parse_url["scheme"] = "http";
}
if(empty($parse_url["host"]) && !empty($parse_url["path"])) {
// Strip slash from the beginning of path
$parse_url["host"] = ltrim($parse_url["path"], '\/');
$parse_url["path"] = "";
}
$return_url = "";
// Check if scheme is correct
if(!in_array($parse_url["scheme"], array("http", "https", "gopher"))) {
$return_url .= 'http'.'://';
} else {
$return_url .= $parse_url["scheme"].'://';
}
// Check if the right amount of "www" is set.
$explode_host = explode(".", $parse_url["host"]);
// Remove empty entries
$explode_host = array_filter($explode_host);
// And reassign indexes
$explode_host = array_values($explode_host);
// Contains subdomain
if(count($explode_host) > 2) {
// Check if subdomain only contains the letter w(then not any other subdomain).
if(substr_count($explode_host[0], 'w') == strlen($explode_host[0])) {
// Replace with "www" to avoid "ww" or "wwww", etc.
$explode_host[0] = "www";
}
}
$return_url .= implode(".",$explode_host);
if(!empty($parse_url["port"])) {
$return_url .= ":".$parse_url["port"];
}
if(!empty($parse_url["path"])) {
$return_url .= $parse_url["path"];
}
if(!empty($parse_url["query"])) {
$return_url .= '?'.$parse_url["query"];
}
if(!empty($parse_url["fragment"])) {
$return_url .= '#'.$parse_url["fragment"];
}
return $return_url;
}
echo url_parser('http:/wwww.example.com/lorum.html'); // http://www.example.com/lorum.html
echo url_parser('gopher:/ww.example.com'); // gopher://www.example.com
echo url_parser('http:/www3.example.com/?q=asd&f=#asd'); // http://www3.example.com/?q=asd&f=#asd
echo url_parser('asd://.example.com/folder/folder/'); // http://example.com/folder/folder/
echo url_parser('.example.com/'); // http://example.com/
echo url_parser('example.com'); // http://example.com
echo url_parser('subdomain.example.com'); // http://subdomain.example.com
It's not 100% foolproof, but a 1 liner.
$URL = (((strpos($URL,'https://') === false) && (strpos($URL,'http://') === false))?'http://':'' ).$URL;
EDIT
There was apparently a problem with my initial version if the hostname contain http.
Thanks Trent

PHP - Display results from this 'Detect' array?

re: Home Site = http://mobiledetect.net/
re: this script = Mobile_Detect.php
Download script here: https://github.com/serbanghita/Mobile-Detect
This script functions perfectly detecting the different parameters of a user's device.
However, this is how I am currently detecting these parameters:
// each part of the IF statement is hard-coded = not the way to do this
if($detect->isiOS()){
$usingOS = 'iOS';
}
if($detect->isAndroidOS()){
$usingOS = 'Android';
}
echo 'Your OS is: '.$usingOS;
My goal is to use a FOREACH to iterate thru the various arrays in this script to determine a user's device's parameters. I would need to have the "($detect->isXXXXOS())" be dynamic... (which, would be based upon the KEY). The results would display the KEY. But the detection would be based upon the VALUE.
Also, since my web page uses a REQUIRE to access this script... in the Mobile_Script.php script, the arrays are "protected." I think this is also causing me problems (but I don't know for sure).
Any help is appreciated.
In foreach loop you can call dynamic method look like this :
$array = array('Android','Windows','Linux','Mac');
foreach( $array as $value) {
$method = "is{$value}OS";
if($detect->$method()) {
$os = $value;
echo "Your OS is : {$os}";
}
}
Please rearrange your code what you want. I give you an example.
you can try to use somethin like this:
$OSList = $detect->getOperatingSystems();// will give array of operating system name => match params
foreach($OSList as $os_name=>$os_params/*unused*/)
{
$method = 'is'.$os_name;
if($detect->$method())
{
$usingOS = $os_name;
}
}

Categories