jaaulde/php-ipv4

用于处理IPv4地址和网络环境的PHP类。

v1.1.1 2015-07-29 19:47 UTC

This package is not auto-updated.

Last update: 2024-09-25 15:20:08 UTC


README

Software License Build Status Scrutinizer Code Quality Coverage Status Latest Version on Packagist Total Downloads

用于处理IPv4地址和网络环境的PHP类。

安装

通过 composer

$ composer require jaaulde/php-ipv4

变更日志

请参阅 CHANGELOG 了解最近的变化信息。

测试

$ composer test

许可证

MIT许可证(MIT)。请参阅 许可证文件 获取更多信息。

使用方法

...

示例

警告:这些示例是简化的,没有上下文。在这些示例中使用未经过滤/未经验证的请求变量(例如来自 $_POST)并不代表推荐在您的项目中这样做。

硬编码白名单

<?php

use \JAAulde\IP\V4 as IPv4;

// Define a whitelist - IPs from this address Block are allowed in
$allowed_client_network = new IPv4\Block('192.168.0.0/24');

// Read the IP address of the current client into an Address instance
$client_address = new IPv4\Address($_SERVER['REMOTE_ADDR']);

// Check that the whitelisted address block contains the current client IP
if ($allowed_client_network->contains($client_address)) {
    // Client is on the whitelist, let them in
} else {
    // Client is NOT on the whitelist, deny access
}

数据库驱动的地址阻止

许多PHP应用程序允许管理员为滥用IP地址的地址范围创建黑名单,以减轻管理员的工作负担。这些应用程序中的大多数使用过于复杂的数据库模式来存储表示范围的IP地址,并使用一系列字符串操作来确定IP地址是否属于被禁止的范围。通过应用IPv4地址方案中涉及的实际数学和逻辑,php-ipv4极大地简化了所有这些操作,并提供了对IP地址的更可靠的过滤。

一个示例管理员界面可能提供了一个类似的表单来输入要禁止的地址范围

<form action="ip-ban.php" method="POST">
    <p>
        <label for="first_address">Enter the <em>first</em> address of the range to block:</label>
        <br>
        <input type="text" id="first_address">
    </p>
    <p>
        <label for="last_address">Enter the <em>last</em> address of the range to block:</label>
        <br>
        <input type="text" id="last_address">
    </p>
    <input type="submit" value="Block">
</form>

接收PHP脚本,ip-ban.php 然后会做类似的事情

<?php

use \JAAulde\IP\V4 as IPv4;

try {
    // The Address constructor will fail if first parameter is not in correct format, so
    // form validation is as simple as trying to create instances with the POSted data
    $first_address = new IPv4\Address($_POST['first_address']);
    $last_address = new IPv4\Address($_POST['last_address']);
    
    // The Range constructor will fail if the addresses are not properly ordered, so form validation
    // is as simple as trying to create an instance with the previously created Address instances
    $blacklisted_range = new IPv4\Range($first_address, $last_address);
} catch (Exception) {
    // Invalid data POSTed, take user back to form with error info
    exit();
}

假设已经正确创建了Range实例,我们可以继续存储它。这正是php-ipv4真正开始脱颖而出的地方。而不是将IP的字符串表示存储在数据库中以供以后检索和比较,php-ipv4让我们可以轻松地将IP的整数表示存储在数据库列中,以便以后使用BETWEEN子句进行查询。

给定一个数据库表,该表具有整数值,代表被阻止范围内第一个和最后一个IP地址

CREATE TABLE `ip_range_blocks` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `first_address` int(10) unsigned NOT NULL,
  `last_address` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我们可以请求获取该范围的第一个和最后一个地址的整数值,并将它们存储起来。

<?php

$query = sprintf(
    'INSERT INTO `ip_range_blocks` (`first_address`, `last_address`) VALUES (%s, %s);',
    $blacklisted_range->getFirstAddress()->get(),
    $blacklisted_range->getLastAddress()->get()
);

最后,当我们想要检查客户端的IP地址是否被阻止时,我们可以简单地查询如下

<?php

use \JAAulde\IP\V4 as IPv4;

$client_address = new IPv4\Address($_SERVER['REMOTE_ADDR']);

$query = sprintf(
    'SELECT COUNT(*) FROM `ip_range_blocks` WHERE %s BETWEEN `first_address` AND `last_address`;',
    $client_address->get()
);

如果上述查询返回的计数大于0,则表示客户端的IP地址在禁止列表中。否则,他们可以继续。就这么简单--不需要请求行中的实际数据或迭代比较。

不仅如此。一个更好的管理员界面允许您指定任何IP地址和子网掩码,以点分十进制或CIDR表示法。php-ipv4也可以轻松实现这一点。给定与之前相同的数据库模式和一个将addressmask通过POST发送到ip-ban.php的表单,您只需

<?php

use \JAAulde\IP\V4 as IPv4;

// The same form validation note from the previous example still stands
$blacklisted_network_block = new IPv4\Block($_POST['address'], $_POST['mask']);

$query = sprintf(
    'INSERT INTO `ip_range_blocks` (`first_address`, `last_address`) VALUES (%s, %s);',
    $blacklisted_network_block->getNetworkAddress()->get(),
    $blacklisted_network_block->getBroadcastAddress()->get()
);

检查客户端IP地址是否被列入黑名单的检查将与之前给出的示例相同。