Question

I have a PHP script that include different pages for special referers:

$ref_found = false; 

// get referer if exists 
$referer = false; 
if ( isset($_SERVER['HTTP_REFERER']) ) { 
    $referer = $_SERVER['HTTP_REFERER']; 
    // get content of list.txt 
    $list = explode(chr(10), file_get_contents('list.txt')); 
    foreach ( $list as $l ) { 
        if ( strlen($l) > 0 ) { 
            if ( strpos( $referer, $l ) ) { 
                $ref_found = true; 
            } 
        } 
    } 
} 

// include the correct file 
if ( $ref_found ) { 
    require_once('special_page.html'); 
} else { 
    require_once('regular_page.html'); 
} 

Referer DB is in simple txt file (list.txt) and it looks like this:

domain1.com

domain2.com

domain3.com

Unfortunalty this script works only for last domain from the list (domain3.com).

What shoud I add? \n ?
Or it's better idea to create domains DB in different way?

Was it helpful?

Solution

The problem is that when you explode() your list of domain names, you end up with whitespace around each item. At the very least, you will have a newline (\n) somewhere, since the linebreaks in your file are probably \r\n.

So you're checking against something like " domain1.com" or maybe "\ndomain1.com", or maybe "domain1.com\n". Since this extra whitespace doesn't exists in the referrer header, it's not matching when you expect it to.

By calling trim() on each value you find, you'll get a clean domain name that you can use to do a more useful comparison:

$list = explode("\n", file_get_contents('list.txt'));
foreach ($list as $l) {
    $l =  trim($l);
    if ((strlen($l) > 0) && (strpos($referer, $l) !== false)) {
        $ref_found = true;
        break;
    }
}

I made a couple other minor updates to your code as well:

  1. I switched away from using chr() and just used a string literal ("\n"). As long as you use double-quotes, it'll be a literal newline character, instead of an actual \ and n, and the string literal is much easier to understand for somebody reading your code.

  2. I switched from a "\r" character (chr 10) to a "\n" character (chr 13). There's several different newline formats, but the most common are "\n" and "\r\n". By exploding on "\n", your code will work with both formats, where "\r" will only work with the second.

  3. I combined your two if statements. This is a very minor update that doesn't have much effect except to (in my opinion) make the code easier to read.

  4. I updated your strpos() to do a literal comparison to false (!==). It's probably not an issue with this code because the referrer value will start with http://, but it's a good habit to get into. If the substring happens to occur at the beginning of the parent string, strpos() will return 0, which will be interpreted as false in your original code.

  5. I added a break statement in your loop if you found a matching domain name. Once you find one and set the flag, there's no reason to continue checking the rest of the domains in the list, and break allows you to cancel the rest of the foreach loop.

OTHER TIPS

chr(13) == "\n"
chr(10) == "\r"

"\n" is most likely what you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top