在Laravel 4中将IP地址保存到模型中。

4 浏览
0 Comments

在Laravel 4中将IP地址保存到模型中。

我正在尝试使用Laravel 4将用户IP地址保存到数据库中。

我找到了下面的函数,它返回一个字符串

Request::getClientIp()

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

$table->string('ip_address');

admin 更改状态以发布 2023年5月21日
0
0 Comments

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

由于IPv6地址的最大长度为39个字符。

IPv4将得到支持,因为它的长度不超过15个字符。

0
0 Comments

选项1:使用VARCHAR(45)列
考虑另一个SO问题中的讨论一个IPv6地址的文本表示的最大长度是多少?包括IPv4隧道功能时IPv6的最大长度为45。
因此,一个更安全的迁移命令将是:

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


优点:

  1. 该列是可读的,无需进行转换,即可设置值或查询行以查看。

缺点:

  1. 它比选项2使用更多的空间,事实上几乎要大3倍。 但是,除非您计划拥有数百万行否则不用太担心。

选项2:使用BLOB列
正如@euantorano提供的存储在mysql数据库中的IP地址链接所述,您可以将IP存储为二进制以节省一些空间。
最简单的答案是使用:

$table->binary('ip_address');


优点:

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

缺点:

  1. 您将需要首先使用类似PHP inet_pton()的工具将IP地址字符串转换为二进制。由于以二进制格式存储,因此该列将无法直接读取。如果尝试直接查询,您将看到奇怪的字符或空白。您可能想看看我在选项3中存储和检索IP地址的方法。
  2. Laravel中的查询构建器,尽管调用的方法为“binary”,但实际上会为您创建BLOB列BLOB存储在表外在行缓冲区之外,这可能意味着较低的性能。而且确实没有理由不使用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建议的那样。 随意以您的方式创建其余部分的表。

从这里开始,您可以使用PHP的inet_pton()inet_ntop()来将IP地址字符串转换为二进制或将二进制转换为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。非常实用!

0