PHP爆炸仅适用于最后一行

时间:2013-07-03 05:49:40

标签: php explode http-referer

我有一个PHP脚本,包含特殊引用的不同页面:

$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在简单的txt文件(list.txt)中,它看起来像这样:

  

domain1.com

     

domain2.com

     

domain3.com

不幸的是,此脚本仅适用于列表中的最后一个域(domain3.com)。

我添加了什么? \n
或者以不同的方式创建域DB更好?

2 个答案:

答案 0 :(得分:2)

问题在于,当您explode()域名列表时,您最终会在每个项目周围留下空白。至少,你会在某个地方换行(\n),因为你文件中的换行符可能是\r\n

因此,您要检查" domain1.com""\ndomain1.com""domain1.com\n"之类的内容。由于引用者标题中不存在这个额外的空格,因此它在您期望的时候不匹配。

通过在您找到的每个值上调用trim(),您将获得一个可用于进行更有用比较的干净域名:

$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;
    }
}

我还对您的代码进行了一些其他的小更新:

  1. 我转而使用chr(),只使用了字符串文字("\n")。只要你使用双引号,它就是一个字面换行符,而不是实际的\n,对于读取你代码的人来说,字符串文字更容易理解。 / p>

  2. 我从"\r"字符(chr 10)切换到"\n"字符(chr 13)。有几种不同的换行格式,但最常见的是"\n""\r\n"。通过"\n"爆炸,您的代码将适用于两种格式,其中"\r"仅适用于第二种格式。

  3. 我合并了你的两个if语句。这是一个非常小的更新,除了(在我看来)使代码更容易阅读之外没有太大的影响。

  4. 我更新了您的strpos()以进行与false(!==)的字面比较。这可能不是这个代码的问题,因为引用者值将以http://开头,但这是一个很好的习惯。如果子字符串碰巧发生在父字符串的开头,strpos()将返回0,这将在原始代码中被解释为false。

  5. 如果您找到了匹配的域名,我在您的循环中添加了break语句。一旦找到并设置了标记,就没有理由继续检查列表中的其余域,break允许您取消foreach循环的其余部分。

    < / LI>

答案 1 :(得分:0)

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

"\n"很可能是您想要的。