通过PHP阻止或重定向坏用户代理或机器人

时间:2013-08-08 01:36:56

标签: php arrays string bots

我在堆栈溢出时发现了这个方法非常好

$badAgents = array('fooAgent','blahAgent', 'etcAgent');
if(in_array($_SERVER['HTTP_USER_AGENT'],$badAgents)) {
    exit();
}

BUT

问题是字符串需要与数组中的字符串完全匹配。

我需要一个新方法来询问用户代理是否包含(在字符串的任何部分中)数组中的一个字符串(不完全匹配只是询问它是否包含其中一个字符/单词)数组中的几个选项)...所以我提出了这个:

$badAgents = array('google','libwww');

if (strpos(in_array(strtolower($_SERVER['HTTP_USER_AGENT']))), $badAgents) == true) {
    exit();
}

它没有用,但我认为它可以用于小调整。

非常感谢你们!

3 个答案:

答案 0 :(得分:0)

通常,最佳做法是使用特征检测而不是用户代理切换。

但是,在这种情况下,您的括号展示位置似乎已关闭。另外,我重写了相等性以使其更清晰(从some values may evaluate to FALSE开始)。

if (strpos(in_array(strtolower($_SERVER['HTTP_USER_AGENT'])), $badAgents) !== FALSE) {
    exit();
}

答案 1 :(得分:0)

我无法发表评论,因此需要将此作为答案发布。 请注意strpos http://php.net/manual/en/function.strpos.php上的警告 当字符串的位置为0(字符串的开头)时,上面的代码将无法正常工作。

此外,代码更进一步。你不能对in_array(boolean)的结果进行strpos。

我看到的唯一方法是迭代数组并为每个元素执行strpos(假设坏代理数组包含要查找的子字符串)。

更新示例:

$badAgents = array('google','libwww','chrome');
$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
foreach($badAgents as $badAgent)
{
    if (strpos($userAgent, $badAgent) !== false)
    {
        exit();
    }
}

可运行的例子:

<?php
$badAgents = array('google','libwww','chrome');

//$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
$userAgent = strtolower('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11');
foreach($badAgents as $badAgent)
{
    if (strpos($userAgent, $badAgent) !== false)
    {
        exit();
    }
}

尽管起初不太清楚get_browser()是一条更好更清洁的路线(如Steven Liao所建议)

答案 2 :(得分:0)

问题是 in_array 会检查是否存在完全匹配。

如果要检查字符串是否包含,可以迭代数组中的每个元素:

foreach ($badAgents as $bad_user_agent) {
    if (stripos($_SERVER['HTTP_USER_AGENT'], $bad_user_agent) !== false) {
         exit();
    }
}

P.S。请注意,我使用了不区分大小写的stripos