61

How can I get the byte array from some string which can contain numbers, letters and so on? If you are familiar with Java, I am looking for the same functionality of the getBytes() method.

I tried a snippet like this one:

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

but without success, so any kind of help will be appreciated.

PS: Why do I need this at all!? Well, I need to send a byte array via fputs() to a server written in Java...

dokaspar
  • 8,186
  • 14
  • 70
  • 98
Splendid
  • 1,317
  • 4
  • 20
  • 41

6 Answers6

97

@Sparr is right, but I guess you expected byte array like byte[] in C#. It's the same solution as Sparr did but instead of HEX you expected int presentation (range from 0 to 255) of each char. You can do as follows:

$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

By using var_dump you can see that elements are int (not 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) }

Be careful: the output array is of 1-based index (as it was pointed out in the comment)

Bronek
  • 10,722
  • 2
  • 45
  • 46
  • 34
    Note to googlers: the resulting array from unpack('C*' has a 1 based index, not 0. Just took me 20 minutes of debugging before I even thought to check. – Steven Jeffries Jun 18 '16 at 22:12
  • 8
    To fix the 1-based index thing you can use `array_values($byte_array)` – josemmo Mar 11 '20 at 10:12
28
print_r(unpack("H*","The quick fox jumped over the lazy brown dog"))

Array ( [1] => 54686520717569636b20666f78206a756d706564206f76657220746865206c617a792062726f776e20646f67 ) 

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

You can split the result into two-hex-character chunks if necessary.

Sparr
  • 7,489
  • 31
  • 48
  • 1
    This isn't a solution for a problem! – Splendid May 23 '09 at 19:02
  • 1
    @Splendid why do you say that? – Sparr Dec 15 '10 at 04:14
  • 4
    byte array is an array of bytes, not a hex string – Nux Dec 01 '11 at 11:38
  • 1
    @Nux the example in the question uses ord() which will put the numeric ascii value of each character into the result string. If this behavior is not desired, please re-phrase or re-post the question with an example input and output. – Sparr Jan 21 '12 at 16:30
  • As he said "Well I need to send via fputs() bytearray to server written in java..." and solution he tried didn't work. So I assume he didn't really need ord. But yes, clarification would be nice. – Nux Jan 23 '12 at 18:21
  • @Sparr how to do the reverse? is there a easy way? – vinicius gati Apr 30 '18 at 13:22
  • 1
    @viniciusgati look into the docs for `pack` which is the inverse of `unpack`, and takes the same sorts of parameters. – Sparr May 01 '18 at 20:55
11

PHP has no explicit byte type, but its string is already the equivalent of Java's byte array. You can safely write fputs($connection, "The quick brown fox …"). The only thing you must be aware of is character encoding, they must be the same on both sides. Use mb_convert_encoding() when in doubt.

soulmerge
  • 73,842
  • 19
  • 118
  • 155
7

You could try this:

$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);
karim79
  • 339,989
  • 67
  • 413
  • 406
6

In PHP, strings are bytestreams. What exactly are you trying to do?

Re: edit

Ps. Why do I need this at all!? Well I need to send via fputs() bytearray to server written in java...

fputs takes a string as argument. Most likely, you just need to pass your string to it. On the Java side of things, you should decode the data in whatever encoding, you're using in php (the default is iso-8859-1).

troelskn
  • 115,121
  • 27
  • 131
  • 155
4

I found several functions defined in http://tw1.php.net/unpack are very useful.
They can covert string to byte array and vice versa.

Take byteStr2byteArray() as an example:

<?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]);
}
?>
Albert Liao
  • 149
  • 3
  • Hi Albert, thank you for this answer. How would I pass all the printf("0x%02x ", $byte_array[$i]); after the loop as one object? e.g. as an array of bytes to a COM object in Php? – Joseph Feb 08 '17 at 14:47