0

我想要一个基本脚本,如果用户 IP 在被禁止 IP 的数据库中,它将在页面顶部消失。到目前为止,我有一个脚本将插入一个具有自动递增 ID 的 IP 和 IP。我正在使用 PDO 库,如何从数据库中获取返回的数组并检查 in_array 是否存在?

这是我返回数据库信息的方式。

$query = " 
    SELECT 
        id, 
        ip
    FROM banned 
"; 

try 
{ 

    $stmt = $db->prepare($query); 
    $stmt->execute(); 
} 
catch(PDOException $ex) 
{ 

    die("Failed to run query: " . $ex->getMessage()); 
} 


$rows = $stmt->fetchAll();

然后这只是我写的一个快速脚本,只是死在页面顶部并重定向。

if(in_array($_SERVER['REMOTE_ADDR'], $row["ip"])) 
{ 
header("Location: banned.php")
die("Banned!"); 
}

我的总体问题是,如何获取获取的数据并将其放入数组中?

4

2 回答 2

0

使用该ip2long()函数将 IP 地址转换为整数。将这些整数存储在数据库中,并改用以下查询。正如 GolezTroll 在评论中指出的那样,确保整数字段是UNSIGNED.

$query = 'SELECT id, ip FROM banned WHERE ip = ';
$query .= ip2long($_SERVER['REMOTE_ADDR']);
$query .= ' LIMIT 1';

这样,您的banned表对索引非常友好,并且您最多只能从表检索一个条目。您当前的代码每次都会获取每个条目,从而在您的 Web 和 mysql 服务器上施加相当大的负载。

此外,您可能可以id从禁止表中删除该列,因为该ip列本身应该用作主键就可以了。

于 2012-11-28T23:10:48.987 回答
0

不。将所有这些地址查询到一个数组中是一种浪费。只需使用这样的查询:

SELECT 
  CASE WHEN EXISTS
    (SELECT 
      'x' 
    FROM 
      banned 
    WHERE 
      ip = :ip) THEN
    'Y'
  ELSE
    'N'
  END AS IsBanned

当然,您必须为 :IP 填写正确的 IP 地址。此查询始终只返回 1 条记录。如果 IP 地址被禁止,则该记录始终包含“Y”,如果不是,则始终包含“N”。即使您不小心禁止了两次 IP,查询也会继续工作,尽管我会通过在该字段上添加唯一约束(唯一索引)来防止这种情况。

但是请注意,IP 禁止并不理想。许多人每天仍然拥有不同的 IP 地址。这意味着他们仍然可以访问您的网站,而无辜的其他人则不能。此外,整个家庭和公司都使用相同的 IP,因此阻止 1 个用户可以阻止整个公司的数千人。

IP 地址(即 IPv4)可以存储在整数字段中。但是请注意,如果您通过参数传递 IP 地址,则必须将其作为字符串传递,即使该字段本身是整数。MySQL 整数参数是有符号的 32 位。这意味着以 128 或更高开头的 IP 地址会遇到麻烦。它会打乱你的比较。

于 2012-11-28T23:10:49.597 回答