首页 > 解决方案 > 如何在 PHP 中将此字符串转换为人类可读的 IP 地址?

问题描述

我有一个代表 IPv4 地址的字符串:

$ip = '\x7F\0\0\x01';

当我试图将其传递给它时,inet_ntop($ip)它让我感到悲伤:

PHP 警告:inet_ntop():in_addr 值无效

如果我使用双引号手动声明变量,它可以工作:

$ip = "\x7F\0\0\x01";
inet_ntop($ip); // "127.0.0.1"

但是,我没有手动声明这些变量。我正在处理一个对象中给我的东西。

如何转换'\x7F\0\0\x01'inet_ntop()可以接受的字符串?

换句话说,我怎样才能让 PHP 从字面上解析一个字符串,就好像我用双引号手动声明它一样?


一些有趣的事实:

gettype('\x7F\0\0\x01'); // string
gettype("\x7F\0\0\x01"); // string
ord('\x7F\0\0\x01'); // 92
ord("\x7F\0\0\x01"); // 127
implode(unpack('H*', '\x7F\0\0\x01')); // 5c7837465c305c305c783031
implode(unpack('H*', "\x7F\0\0\x01")); // 7f000001
mb_detect_encoding('\x7F\0\0\x01'); // ASCII
mb_detect_encoding("\x7F\0\0\x01"); // UTF-8
"\x7F\0\0\x01" == '\x7F\0\0\x01'; // false
// and for the haters
long2ip('\x7F\0\0\x01'); // PHP Warning:  long2ip() expects parameter 1 to be integer, string given

标签: php

解决方案


一种可能性是将字符串解析为其组成部分(以 开头\);将它们转换为十进制等效值并用于chr取回原始字符。然后可以将它们连接成一个适合的字符串inet_ntop

$ip = '\x7F\0\0\x01';
preg_match_all('/\\\x?([\dA-F]+)/', $ip, $parts);
$ip = implode('', array_map(function ($v) { return chr(hexdec($v)); }, $parts[1]));
echo inet_ntop($ip);

另一种选择是pack在剥离\x零件并替换为 之后\0使用00

$ip = '\x7F\0\0\x01';
$ip = pack('H*', str_replace(array('\x', '\0'), array('', '00'), $ip));
echo inet_ntop($ip);

在这两种情况下,输出都是:

127.0.0.1

3v4l.org 上的演示


推荐阅读