laravel 4 将 IP 地址保存到模型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17795517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
laravel 4 saving ip address to model
提问by user391986
I'm trying to save a user ip address to my database using Laravel 4. I found the following function which returns a string
我正在尝试使用 Laravel 4 将用户 IP 地址保存到我的数据库中。我发现以下函数返回一个字符串
Request::getClientIp()
How would I store this in my model? Just a string or is there a more efficient way?
我将如何将其存储在我的模型中?只是一个字符串还是有更有效的方法?
$table->string('ip_address');
回答by Unnawut
Option 1: Use VARCHAR(45) column
选项 1:使用 VARCHAR(45) 列
Considering the discussion in another SO question Maximum length of the textual representation of an IPv6 address?, the maximum length of IPv6 is 45 when including the IPv4 tunneling feature.
考虑在另一个 SO 问题中的讨论IPv6 地址的文本表示的最大长度?,当包括 IPv4 隧道功能时,IPv6 的最大长度为 45。
Thus, a safer migration command would be:
因此,更安全的迁移命令是:
$table->string('ip_address', 45);
Pros:
优点:
- The column is human-readable. No need for conversions when setting the value or querying the row out for viewing.
- 该列是人类可读的。设置值或查询行以供查看时无需转换。
Cons:
缺点:
- It uses more space than Option 2, almost 3 times larger in fact. But I wouldn't worry much unless you are planning it have millions of rows.
- 它比选项 2 使用更多的空间,实际上几乎是 3 倍。但我不会太担心,除非你计划它有数百万行。
Option 2: Use BLOB column
选项 2:使用 BLOB 列
As @euantorano provided the link to IP address storing in mysql database, you may store the IP as binary to save some space.
由于@euantorano 提供了存储在 mysql 数据库中的 IP 地址的链接,您可以将 IP 存储为二进制文件以节省一些空间。
The simplest answer would be to use:
最简单的答案是使用:
$table->binary('ip_address');
Pros:
优点:
- Store IP addresses in binary will save you some space.
- 以二进制形式存储 IP 地址将为您节省一些空间。
Cons:
缺点:
You will need to convert the IP address string to binary first using something like PHP's inet_pton(). The column will not be directly readable since it is stored in binary format. You will see weird characters or blank if tried to query it out directly. You may want to look at my way to store and retrieve the IP address in Option 3 below.
The query builder in Laravel, despite the method being called binary, will actually create a BLOB columnfor you. BLOB is stored off the table, out of the row buffer, which possiblymeans a lower performance. And there really isn't a reason not to use BINARY column type since we know IP addresses aren't that long for BLOB to be necessary.
您需要先使用 PHP 的inet_pton() 之类的东西将 IP 地址字符串转换为二进制文件。该列不能直接读取,因为它以二进制格式存储。如果尝试直接查询,您会看到奇怪的字符或空白。您可能想看看我在下面的选项 3 中存储和检索 IP 地址的方法。
Laravel 中的查询构建器,尽管该方法被称为二进制,但实际上会为您创建一个 BLOB 列。BLOB被存储从桌子上,从行缓冲器的,这可能意味着一个较低的性能。并且确实没有理由不使用 BINARY 列类型,因为我们知道 IP 地址对于 BLOB 来说没有那么长是必要的。
Option 3: Use VARBINARY(16) column
选项 3:使用 VARBINARY(16) 列
Laravel's query builder produces a BLOB column for the example in Option 2. If you are using MySQL, you will want to use VARBINARY(16) instead of BLOB for better performance.
Laravel 的查询构建器为选项 2 中的示例生成一个 BLOB 列。如果您使用 MySQL,您将需要使用 VARBINARY(16) 而不是 BLOB 以获得更好的性能。
Migration script:
迁移脚本:
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');
}
}
Obviously the only important part above is the DB::statement(...). We need to use raw queries as Taylor Otwell suggested. Feel free to create the rest of the table your way.
显然,上面唯一重要的部分是 DB::statement(...)。我们需要使用Taylor Otwell 建议的原始查询。随意创建表格的其余部分。
From here you can use PHP's inet_pton()and inet_ntop()to convert the IP address strings to binary and vice versa.
从这里您可以使用 PHP 的inet_pton()和inet_ntop()将 IP 地址字符串转换为二进制,反之亦然。
Pros:
优点:
- Saves space compared to Option 1
- Better DB performance compared to Option 2
- 与选项 1 相比节省空间
- 与选项 2 相比更好的数据库性能
Cons:
缺点:
- Like Option 2, you need to either manually convert back and forth between binary and human-readable string, or use Eloquent model with a pair custom accessor/mutator which I will demonstrate below.
- 与选项 2 一样,您需要手动在二进制字符串和人类可读字符串之间来回转换,或者使用带有一对自定义访问器/修改器的 Eloquent 模型,我将在下面演示。
Extra credit: Add custom Eloquent accessor/mutator (optional):
额外功劳:添加自定义 Eloquent 访问器/修改器(可选):
Here is where I find Eloquent really useful. You can set your own accessor/mutator to your Eloquent model and you can get/set via your model's instance variable as usual.
这是我发现 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);
}
}
Now if you do:
现在如果你这样做:
$log = new MyLog;
$log->ip_address = '192.168.0.1';
$log->save();
The IP address will be saved as binary correctly. And you can do:
IP 地址将正确保存为二进制文件。你可以这样做:
$log = MyLog::find(1);
echo $log->ip_address;
And it will echo out 192.168.0.1. Very useful!
它会回显 192.168.0.1。很有用!
回答by yassine
$table->string('ip_address', 39);
Because the maximum length of an IPv6 address is 39.
因为 IPv6 地址的最大长度是 39。
IPv4 will be supported as it's length doesn't exceeds 15.
IPv4 将被支持,因为它的长度不超过 15。
回答by Kanin Peanviriyakulkit
From @Unnawut.
来自@Unnawut。
You need to change from binary(16)
to varbinary(16)
if you want to deal with both ipv4 and ipv6 in the same field.
你需要从改变binary(16)
到varbinary(16)
,如果你想同时处理IPv4和IPv6在同一领域。
But if you need to deal only ip v4 just INT UNSIGNED
但是如果你只需要处理ip v4就可以了 INT UNSIGNED
If you want to deal only ip v6 BINARY(16)
如果你只想处理ip v6 BINARY(16)
ref: MYSQL - SELECT IP v4/v6, inet_pton & bin2hex
参考:MYSQL - 选择 IP v4/v6、inet_pton 和 bin2hex