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



我在堆栈溢出上发现了这种方法,它的效果非常好

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

但是

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

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

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

它不起作用,但我认为它会起作用的小调整。

提前感谢各位!

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

然而,在这种情况下,你的括号位置似乎不正确。此外,我重写了等式,使其更加清晰(因为有些值可能会计算为FALSE)。

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

问题是in_array检查一个EXACT匹配。

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

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

附言:请注意,我使用了不区分大小写的的stripos

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

此外,代码被进一步破坏。不能对in_array(布尔值)的结果执行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所建议的)

最新更新