4

我目前在我的图像站点上有一个喜欢功能,它根据唯一的 $imgids 将用户 IP 存储在数据库中。

IP 当前存储为字符串。为了节省空间,我不想将 IP 存储为带小数点的字符串,而是存储为 32 位整数(每个整数 1 位,字符串中每个字符 1 个字节)。我认为这可以节省大量空间,因为我有可能让 n 个独特的 IP 喜欢 x 个图像......

因此,给定字符串“109.181.156.221”,数字最多为 12 个字节,每个小数点 + 3 个字节……所以 15 个字节 * 5000 个 IP * 10 个图像 ID = 7.1 Mb

与 32 位 109181156221 相比,4 字节 * 5000 IP * 100 图像 ID = 2 Mb

所以,在我插入 IP 之前,我想使用正则表达式来删除小数,然后将 IP 存储为数字......“109.181.156.221”-> 109181156221 我是正则表达式的新手,但我已经试过这个,但它不会工作:

$ipINT = preg_replaceAll("\\.+$", "" , $ipString);

所以我的问题是:

1) 在 Mysql 数据库中节省空间是否重要?这值得麻烦吗?

2)我的正则表达式在哪里?

3)如果我想读它,我能把它转换回来吗?

有什么想法吗?

谢谢!

4

4 回答 4

4

您可以使用ip2long (),然后它应该适合 unsigned int 列。

于 2013-02-21T17:50:12.587 回答
3

有不同的方法可以做到这一点:

正确的方式:

通过让数据库为您进行转换。您必须将 ip 存储在数据库中INT(10) UNSIGNED并使用INET_ATONINET_NTOA

SELECT INET_ATON("109.181.156.221"); // result 1840618717
SELECT INET_NTOA("1840618717"); // result 109.181.156.221

另一种方法:

通过使用 PHP 内部函数ip2long() & long2ip()然后将其存储在数据库中:

$ipINT = ip2long('109.181.156.221'); // result 1840618717
$ip = long2ip('1840618717'); // result 109.181.156.221

非标准方式:

通过删除点并在需要时添加“0”以便能够将其转换回来:

function ip2int($ip){
  $chunks = explode(".", $ip);
  $int = '';
  foreach($chunks as $chunk){
    $int .= str_pad($chunk, 3, '0', STR_PAD_LEFT);
  }
  return $int;
}

function int2ip($int){
  $chunks = str_split($int, 3);
  $c = count($chunks);
  $ip = ltrim($chunks[0], '0');
  for($i=1;$i<$c;$i++){
    $ip .= '.' . ltrim($chunks[$i], '0');
  }
  return($ip);
}

echo ip2int("109.1.156.5") . '<br>'; // result 109001156005
echo int2ip("109001156005"); // result 109.1.156.5

修复你的正则表达式:

$ip = "109.181.156.221";
$replace = preg_replace("/\./", "", $ip); // This will remove all the dots
echo $replace; // result 109181156221
于 2013-02-21T19:33:30.663 回答
2

使用该ip2long()功能存储 IP 地址 - Unsigned INT(10) 应该很棒。

用于long2ip()解码。

http://php.net/manual/en/function.ip2long.php

您的解决方案不适用于像 1.123.123.123 这样的 IP 地址,因为您不知道在哪里恢复小数点。存储 IP 地址的正确方法是使用上述方法。

于 2013-02-21T17:51:15.527 回答
0

如果您只想提取不需要正则表达式的数字,您可以使用:

filter_var('109.181.156.221', FILTER_SANITIZE_NUMBER_INT);

会给你109181156221

但我认为您无法将其转换回 IP 形式。

我会用点存储它。

于 2013-02-21T17:55:09.443 回答