我正在尝试使用Laravel 4将用户IP地址保存到我的数据库。 我发现以下函数返回一个字符串
Request::getClientIp()
我如何将它存储在我的模型中?只是一个字符串或是否有更有效的方式?
$table->string('ip_address');
答案 0 :(得分:41)
选项1:使用VARCHAR(45)列
考虑到另一个SO问题Maximum length of the textual representation of an IPv6 address?中的讨论,在包含IPv4隧道功能时,IPv6的最大长度为45。
因此,更安全的迁移命令将是:
$table->string('ip_address', 45);
优点:
缺点:
选项2:使用BLOB列
由于@euantorano提供了IP address storing in mysql database的链接,您可以将IP存储为二进制以节省一些空间。
最简单的答案是使用:
$table->binary('ip_address');
优点:
缺点:
您需要先使用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地址字符串转换为二进制,反之亦然。
<强>优点:强>
<强>缺点:强>
额外信用:添加自定义Eloquent访问者/ mutator(可选):
这是我发现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。非常有用!
答案 1 :(得分:1)
$table->string('ip_address', 39);
因为IPv6地址的最大长度为39。
支持IPv4,因为它的长度不超过15。
答案 2 :(得分:0)
来自@Unnawut。
如果要在同一字段中处理ipv4和ipv6,则需要从binary(16)
更改为varbinary(16)
。
但如果你只需要处理ip v4 INT UNSIGNED
如果您只想处理ip v6 BINARY(16)