【发布时间】:2013-01-03 20:34:35
【问题描述】:
我知道这个问题已经被问过很多次了,但我找不到任何最终解决方案;所以这里是:
如何在不知道数据库的情况下使用最佳实践在数据库中存储 IP(IPv4 和 IPv6)?这以用于 DB 抽象目的,例如 PHP PDO。
顺便说一句,我有 PHP 5.2.17,因为我需要 Windows 上的 PEAR。
人们一直建议将其存储为 varbinary(16) 并使用 mysql 函数 inet6_ntop 和 inet6_pton 将 IP 作为字符串来回传递;像Extending MySQL 5 with IPv6 functions 建议。在 PHP 中,函数 inet_pton() 和 inet_ntop() 可以将 IPv4 和 IPv6 来回转换为二进制格式,如ThiefMaster in this question is suggesting,但不清楚如何将二进制内容传递到 SQL INSERT/UPDATE 字符串(并且这些 php 函数仅由php 5.3.0 on windows 提供,即使可以对这些函数进行逆向工程)。我真的很喜欢Jake 和his results with regards to integer representations of IPs in DBs 所做的事情,如果我要将它实现到我的数据库中,这可能会在遥远的、不可预见的未来派上用场,但是我不确定数据库抽象的数据库交叉兼容性使用 PHP PDO。 This post 似乎提供了一个关于存储二进制值的接近答案,但未转义的二进制注入字符串不是潜在的危险吗?另外,如果您遵循这条路线,如果某些开发人员想要进行一些快速查找,有多少 DB 可以将 varbinary(16)/int(128bit) 转换为代表性 IP?
在我看来,最简单的方法是将ip string as-is 插入varchar(45)。但是那些想要遵循复杂路线的人如何使用 inet_ntop() 和 inet_pton() 函数在 PHP(逆向工程 as djmaze(AT)dragonflycms(.)org 或 MagicalTux at FF dot st 建议)中将 IPv6 存储和检索为二进制文件?有人可以举个例子,使用来自<?php $strIP = "2001:4860:b002::68"; ?> 的 PDO,使用 INSERT 然后 SELECT 准备好的语句?
如您所见,我已经完成了研究,但我并不清楚 IPv6 的最终良好实践。
【问题讨论】:
-
这真的取决于您需要能够使用 IP 地址做什么。如果您只需要存储和检索它,或者将其与另一个 IP 地址进行完全匹配,则可以使用文本字符串。然后,您可以在二进制格式客户端进行所有转换(无论如何,在插入时您都需要这样做一次,以保证地址是规范形式)。如果您需要进行涉及前缀长度匹配的数据库查询(例如,给我前缀 2001:db8:1234::/46 所涵盖的所有 IP 地址),文本字符串会变得更加不方便。
标签: database store ipv6 abstract