我正在尝试使用 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);
优点:
- 该列是人类可读的。设置值或查询行进行查看时无需进行转换。
缺点:
- 它比选项 2 使用更多的空间,实际上几乎大了 3 倍。但我不会太担心,除非您计划它有数百万行。
选项 2:使用 BLOB 列
@euantorano 提供了 IP address storing in mysql database 的链接,您可以将IP存储为二进制以节省一些空间。
最简单的答案是使用:
$table->binary('ip_address');
优点:
- 以二进制形式存储 IP 地址可以节省一些空间。
缺点:
您需要首先使用 PHP 的 inet_pton() 将 IP 地址字符串转换为二进制。 。该列无法直接读取,因为它以二进制格式存储。如果尝试直接查询,您会看到奇怪的字符或空白。您可能想看看我在下面的选项 3 中存储和检索 IP 地址的方法。
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 相比节省空间
- 与选项 2 相比,数据库性能更好
缺点:
- 与选项 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/