我有一个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更好?
答案 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;
}
}
我还对您的代码进行了一些其他的小更新:
我转而使用chr()
,只使用了字符串文字("\n"
)。只要你使用双引号,它就是一个字面换行符,而不是实际的\
和n
,对于读取你代码的人来说,字符串文字更容易理解。 / p>
我从"\r"
字符(chr 10)切换到"\n"
字符(chr 13)。有几种不同的换行格式,但最常见的是"\n"
和"\r\n"
。通过"\n"
爆炸,您的代码将适用于两种格式,其中"\r"
仅适用于第二种格式。
我合并了你的两个if
语句。这是一个非常小的更新,除了(在我看来)使代码更容易阅读之外没有太大的影响。
我更新了您的strpos()
以进行与false(!==
)的字面比较。这可能不是这个代码的问题,因为引用者值将以http://
开头,但这是一个很好的习惯。如果子字符串碰巧发生在父字符串的开头,strpos()
将返回0
,这将在原始代码中被解释为false。
如果您找到了匹配的域名,我在您的循环中添加了break
语句。一旦找到并设置了标记,就没有理由继续检查列表中的其余域,break
允许您取消foreach
循环的其余部分。
答案 1 :(得分:0)
chr(13) == "\n"
chr(10) == "\r"
"\n"
很可能是您想要的。