在PHP中将字符串转换为字节数组

61

我该如何从包含数字、字母等的字符串中获取字节数组?如果您熟悉Java,我正在寻找类似于getBytes()方法的功能。

我尝试了以下片段:

for($i = 0; $i < strlen($msg); $i++){
    $data.=ord($msg[$i]);
        //or $data[]=ord($msg[$1]); 
}

我尝试了一些方法,但都没有成功,所以非常感谢任何形式的帮助。

PS:为什么我需要这个?因为我需要通过fputs()将一个字节数组发送到一个用Java编写的服务器...

6个回答

97

@Sparr是正确的,但我猜你期望像C#中的byte[]这样的字节数组。 这与Sparr所做的相同,只是您期望每个char范围为0到255int表示(而不是十六进制)。 您可以按以下方式操作:

$byte_array = unpack('C*', 'The quick fox jumped over the lazy brown dog');
var_dump($byte_array);  // $byte_array should be int[] which can be converted
                        // to byte[] in C# since values are range of 0 - 255

通过使用 var_dump 函数,您可以看到元素的类型为 int(而不是 string)。

   array(44) {  [1]=>  int(84)  [2]=>  int(104) [3]=>  int(101) [4]=>  int(32)
[5]=> int(113)  [6]=>  int(117) [7]=>  int(105) [8]=>  int(99)  [9]=>  int(107)
[10]=> int(32)  [11]=> int(102) [12]=> int(111) [13]=> int(120) [14]=> int(32)
[15]=> int(106) [16]=> int(117) [17]=> int(109) [18]=> int(112) [19]=> int(101)
[20]=> int(100) [21]=> int(32)  [22]=> int(111) [23]=> int(118) [24]=> int(101)
[25]=> int(114) [26]=> int(32)  [27]=> int(116) [28]=> int(104) [29]=> int(101)
[30]=> int(32)  [31]=> int(108) [32]=> int(97)  [33]=> int(122) [34]=> int(121)
[35]=> int(32)  [36]=> int(98)  [37]=> int(114) [38]=> int(111) [39]=> int(119)
[40]=> int(110) [41]=> int(32)  [42]=> int(100) [43]=> int(111) [44]=> int(103) }

注意:输出数组是从1开始计数的(正如评论中所指出的)


34
注给谷歌搜索的开发人员:unpack('C*') 函数返回的数组索引基于 1 而非 0。在我进行了将近 20 分钟的调试之前,我甚至没有想到去检查这一点。 - Steven Jeffries
8
为了修复基于1的索引问题,您可以使用array_values($byte_array) - josemmo

28
print_r(unpack("H*","The quick fox jumped over the lazy brown dog"))

Array ( [1] => 54686520717569636b20666f78206a756d706564206f76657220746865206c617a792062726f776e20646f67 ) 

T = 0x54, h = 0x68, ...

如果需要,您可以将结果拆分为两个十六进制字符块。


1
这不是解决问题的方案! - Splendid
1
@Splendid 你为什么这么说? - Sparr
4
字节数组是一组字节,而不是十六进制字符串。 - Nux
1
@Nux 问题中的示例使用了 ord() 函数,该函数会将每个字符的 ASCII 数值转换为结果字符串。如果不希望这种行为,请重新措辞或重新发布问题,并附上输入和输出示例。 - Sparr
1
@viniciusgati请查看pack的文档,它是unpack的反向操作,并且使用相同类型的参数。 - Sparr
显示剩余2条评论

11

PHP没有显式的byte类型,但它的string已经相当于Java的字节数组。你可以安全地写入fputs($connection, "The quick brown fox …")。唯一需要注意的是字符编码,两端必须相同。如果不确定,使用mb_convert_encoding()


7
你可以尝试这个:
$in_str = 'this is a test';
$hex_ary = array();
foreach (str_split($in_str) as $chr) {
    $hex_ary[] = sprintf("%02X", ord($chr));
}
echo implode(' ',$hex_ary);

6
在PHP中,字符串是字节流。您到底想做什么?
关于编辑:
Ps.我为什么需要这个?好吧,我需要通过fputs()将bytearray发送到使用Java编写的服务器...
fputs接受一个字符串作为参数。最有可能的是,您只需要将字符串传递给它即可。在Java方面,您应该解码以php中使用的任何编码方式对数据进行解码(默认为iso-8859-1)。

4
我发现在http://tw1.php.net/unpack中定义的几个函数非常有用。它们可以将字符串转换为字节数组,反之亦然。
以byteStr2byteArray()为例:
<?php
function byteStr2byteArray($s) {
    return array_slice(unpack("C*", "\0".$s), 1);
}

$msg = "abcdefghijk";
$byte_array = byteStr2byteArray($msg);

for($i=0;$i<count($byte_array);$i++)
{
   printf("0x%02x ", $byte_array[$i]);
}
?>

嗨,阿尔伯特,感谢您的回答。我如何将循环后的所有printf("0x%02x ", $byte_array[$i]); 作为一个对象传递?例如,在Php中将其作为字节数组传递给COM对象? - Joseph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接