完整的 PHP+MySQL IPv4 和IPv6解决方案?
我对网络主题不是很了解,但我必须为我的项目存储 IP 地址,并且我想准备好处理 IPv4 和 IPv6。我读过的最佳解决方案似乎是两个 BIGINT 无符号字段,其中一个在 IPv4 的情况下为空:
如何在关系数据库中存储 IPv6 兼容地址< /a> 有人有完整的解决方案吗?
我需要代码从字符串地址(如 $_SERVER['HTTP_CLIENT_IP'] 生成)转换为数值,反之亦然。
非常感谢您的帮助。我想确保我这样做是正确的。
I'm not very knowledgeable about networking topics, but I have to store IP addresses for my project, and I want to be prepared to handle both IPv4 and IPv6. The best solution I've read appears to be two BIGINT unsigned fields where one is null in the case of IPv4:
How to store IPv6-compatible address in a relational database
Does anybody have the complete solution?
I need code to go from a string address (like $_SERVER['HTTP_CLIENT_IP'] produces) to numeric values and vice versa.
Thank you very much for any help. I want to make sure I'm doing this correctly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
或者,您也可以使用 PostgreSQL 等数据库(如果可以的话)。它具有用于存储和搜索 IPv4 和 IPv6 地址及前缀的本机数据类型。输入和输出(通常)以字符串表示形式完成。
如果您必须使用 MySQL,这实际上取决于您想要如何使用地址。如果您想搜索子网、按前缀分组等,那么整数是最有用的。如果您只需要存储它们,那么 varchar 就是最佳选择。
Or you can use a database like PostgreSQL if that is an option. It has native data types for storing and searching IPv4 and IPv6 addresses and prefixes. Input and output are done in string representation (usually).
If you have to use MySQL it really depends on how you want to use the addresses. If you want to search for subnets, group by prefix etc then integers are the most useful. If you just need to store them then varchar is the way to go.
实际上,我按照人类书写的方式存储序数。因此,IPv6 有 8 个 16 位无符号整数字段,IPv4 有 4 个 8 位无符号整数字段。对我来说,这使得搜索某些网络变得简单,尽管我可以看到 2 个无符号 bigint 也可以很简单。
或者,您可以按照代码中最常用的格式存储它,并按原样检索它。这似乎是一个字符串,大约有 40 个字符长。如果您这样做,您将需要使用 rfc5952 中建议的规范表示形式。
我不能只为你写转换代码;您需要提供一些示例,说明您尝试过但不起作用的方法以及原因。
I actually store the ordinals the way humans write them. So 8 16 bit unsigned integer fields for IPv6 and 4 8 bit unsigned integer fields for IPv4. For me, this makes searching for certain networks simple, though I can see that 2 unsigned bigints can also be simple.
Or you could store it in the format that you have it in most often in your code and will retrieve it as such. Which seems to be a string, one that's about 40 characters long. If you do that you'll want to use a canonical representation like that suggested in rfc5952.
I can't just write the conversion code for you; you'll need to provide some example of what you tried that didn't work, and why.
对于 IP 地址(格式)验证,我目前正在使用它作为我正在做的事情的一部分 - 还不能 100% 确定它完全正确 - 需要向其抛出更多数据(而且我不喜欢我也对私有成员使用了命名约定 - 但这是一个通过重构很容易解决的问题):
编辑:刚刚注意到这依赖于我的变量解析类 VParse - 你几乎可以替换任何实例
VParse::toInt()
具有 PHP 的标准(int)
类型转换功能。For IP address (format) verification, I'm currently using this as part of something I'm working on - not 100% certain that it's entirely correct as yet - need to throw more data at it (and I don't like the naming convention I've used on the private members either - but that's an easy fix with refactoring):
EDIT: just noticed this relies on my variable parsing class VParse - you can pretty much replace any instance of
VParse::toInt()
with PHP's standard(int)
type casting functionality.有关选择 IP 地址列类型的一些提示。
当 IP 存储为人类可读字符串时,IPv4 和 IPv6 的最大长度分别为 VARCHAR(15) 和 VARCHAR(39)。
我们可以通过将数据类型设置为 VARBINARY(16) 以二进制形式存储 IP(IPv4 和 IPv6)。我们可以使用 PHP 函数
inet_pton()
和inet_ntop()
在数据库中存储和检索 IP。使用 VARBINARY 类型的优点:
通过以二进制形式存储 IP,它将消耗更少的磁盘空间,更小的索引大小意味着更好的性能(获取/插入等),更少的内存(RAM)将用于缓存数据/索引。
使用 VARBINARY 类型的缺点:
存储的值不是人类可读的。
Few tips on choosing the column type for IP Addresses.
When IPs are stored as human readable strings, the maximum length of IPv4 and IPv6 is VARCHAR(15) and VARCHAR(39) respectively.
We can store IPs(both IPv4 & IPv6) in binary form by setting data type to VARBINARY(16). We can use PHP functions
inet_pton()
andinet_ntop()
to store and retrieve IP from DB.Pros of using VARBINARY type:
By storing IPs in binary form it will consume less disk space, smaller index size means better performance(fetching/inserting etc.), lesser memory(RAM) will be used to cache the data/indexes.
Cons of using VARBINARY type:
The value stored is not human-readable.