laravel 4 将 IP 地址保存到模型中

标签 laravel ip laravel-4

我正在尝试使用 Laravel 4 将用户 IP 地址保存到我的数据库中。 我发现以下函数返回一个字符串

Request::getClientIp()

我如何将其存储在我的模型中?只是一个字符串还是有更有效的方法?

$table->string('ip_address');

最佳答案

选项 1:使用 VARCHAR(45) 列

考虑另一个SO问题中的讨论Maximum length of the textual representation of an IPv6 address?当包含 IPv4 隧道功能时,IPv6 的最大长度为 45。

因此,更安全的迁移命令是:

$table->string('ip_address', 45);

优点:

  1. 该列是人类可读的。设置值或查询行进行查看时无需进行转换。

缺点:

  1. 它比选项 2 使用更多的空间,实际上几乎大了 3 倍。但我不会太担心,除非您计划它有数百万行。
<小时/>

选项 2:使用 BLOB 列

@euantorano 提供了 IP address storing in mysql database 的链接,您可以将IP存储为二进制以节省一些空间。

最简单的答案是使用:

$table->binary('ip_address');

优点:

  1. 以二进制形式存储 IP 地址可以节省一些空间。

缺点:

  1. 您需要首先使用 PHP 的 inet_pton() 将 IP 地址字符串转换为二进制。 。该列无法直接读取,因为它以二进制格式存储。如果尝试直接查询,您会看到奇怪的字符或空白。您可能想看看我在下面的选项 3 中存储和检索 IP 地址的方法。

  2. Laravel 中的查询生成器,尽管该方法被称为二进制,但实际上会 create a BLOB column为你。 BLOB is stored off the table , out of the row buffer ,这可能意味着性能较低。确实没有理由不使用 BINARY 列类型,因为我们知道 IP 地址对于 BLOB 来说并不是那么长。

<小时/>

选项 3:使用 VARBINARY(16) 列

Laravel 的查询生成器为选项 2 中的示例生成一个 BLOB 列。如果您使用 MySQL,则需要使用 VARBINARY(16) 而不是 BLOB 以获得更好的性能。

迁移脚本:

class CreateMyLogsTable extends Migration {

    public function up()
    {
        Schema::create('my_logs', function(Blueprint $table) {
            $table->increments('id');
        });

        DB::statement('ALTER TABLE `my_logs` ADD `ip_address` VARBINARY(16)');
    }

    public function down()
    {
        DB::statement('ALTER TABLE `my_logs` DROP COLUMN `ip_address`');

        Schema::drop('my_logs');
    }
}

显然上面唯一重要的部分是 DB::statement(...)。我们需要使用原始查询 Taylor Otwell suggested 。请随意按照自己的方式创建表格的其余部分。

从这里您可以使用 PHP 的 inet_pton()inet_ntop()将 IP 地址字符串转换为二进制,反之亦然。

优点:

  1. 与选项 1 相比节省空间
  2. 与选项 2 相比,数据库性能更好

缺点:

  1. 与选项 2 一样,您需要在二进制和人类可读字符串之间手动来回转换,或者使用带有一对自定义访问器/变元的 Eloquent 模型,我将在下面演示。
<小时/>

额外功劳:添加自定义 Eloquent 访问器/修改器(可选):

这是我发现 Eloquent 真正有用的地方。您可以为 Eloquent 模型设置自己的访问器/修改器,并且可以像往常一样通过模型的实例变量获取/设置。

class MyLog extends Eloquent {

    public $timestamps = false;

    public function getIpAddressAttribute($value)
    {
        return inet_ntop($value);
    }

    public function setIpAddressAttribute($value)
    {
        $this->attributes['ip_address'] = inet_pton($value);
    }
}

现在,如果你这样做:

$log = new MyLog;
$log->ip_address = '192.168.0.1';
$log->save();

IP 地址将正确保存为二进制。你可以这样做:

$log = MyLog::find(1);
echo $log->ip_address;

它将回显 192.168.0.1。非常有用!

关于laravel 4 将 IP 地址保存到模型中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17795517/

相关文章:

php - Laravel 5 SQLSTATE [42S22] : Column not found

reactjs - 使用 ReactJS 将 IP 地址从前端发送到服务器 NodeJS

php - 通过互联网从本地 LAN 获取客户端 IP

php - url::laravel 中的上一期

image - 干预图像长宽比

php - 物理删除在 laravel5 中启用软删除的模型?

mysql - Laravel - 获取用户及其角色名称

golang 区分 IPv4 IPv6

mysql - 在 Laravel Query Builder 中合并来自不同数据库的查询

mysql - Laravel 5.5 中的主从配置