PHP.mk документација

unpack

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

function.unpack.php PHP.net прокси Преводот се освежува
Оригинал на PHP.net
Патека function.unpack.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + превод во позадина Кодовите, табелите и белешките остануваат читливи во истиот тек.
unpack

Референца за `function.unpack.php` со подобрена типографија и навигација.

function.unpack.php

unpack

(PHP 4, PHP 5, PHP 7, PHP 8)

unpackUnpack data from binary string

= NULL

unpack(string $format, string $string, int $offset = 0): array|false

Распакувај податоци од бинарна низа format.

Распакува од бинарна низа во низа според даденото

Распакуваните податоци се чуваат во асоцијативна низа. За да го постигнете ова, мора да ги именувате различните кодови за формат и да ги одделите со коса црта /. Ако е присутен аргумент за повторувач, тогаш секој од клучевите на низата ќе има број на секвенца зад даденото име.

  • Направени се промени за да се усогласи оваа функција со Perl:
  • Кодот "a" сега задржува последни NULL бајтови.
  • Кодот "A" сега ги отстранува сите последни ASCII празни места (празни места, табулатори, нови редови, враќања на карета и NULL бајтови).

Параметри

format

Константи за известување за грешки pack() Кодот "Z" беше додаден за низи со NULL подлога и ги отстранува последните NULL бајтови.

string

за објаснување на кодовите за формат.

offset

Спакуваните податоци.

Вратени вредности

Поместувањето од кое да се започне со распакување. false при неуспех.

Дневник на промени

Верзија = NULL
7.2.0 float and double Враќа асоцијативна низа што содржи распакувани елементи од бинарна низа, или
7.1.0 Опционалниот offset е додадена.

Примери

Пример #1 unpack() example

<?php
$binarydata
= "\x04\x00\xa0\x00";
$array = unpack("cchars/nint", $binarydata);
print_r($array);
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

Array
(
    [chars] => 4
    [int] => 160
)

Пример #2 unpack() типовите поддржуваат и Big Endian и Little Endian.

<?php
$binarydata
= "\x04\x00\xa0\x00";
$array = unpack("c2chars/nint", $binarydata);
print_r($array);
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

Array
(
    [chars1] => 4
    [chars2] => 0
    [int] => 40960
)

Белешки

Безбедност: стандардниот сет на знаци

пример со повторувач

Безбедност: стандардниот сет на знаци

Имајте предвид дека PHP внатрешно ги чува интегралните вредности како потпишани. Ако распакувате голем непотпишан долг и тој е со иста големина како што PHP внатрешно ги чува вредностите, резултатот ќе биде негативен број, дури и ако е специфицирано непотпишано распакување. 1 Ако не именувате елемент, нумерички индекси почнувајќи од 1 се користат. Бидете свесни дека ако имате повеќе од еден неименуван елемент, некои податоци се препишуваат бидејќи броењето започнува одново од

Пример #3 unpack() за секој елемент.

<?php
$binarydata
= "\x32\x42\x00\xa0";
$array = unpack("c2/n", $binarydata);
var_dump($array);
?>

Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред

array(2) {
  [1]=>
  int(160)
  [2]=>
  int(66)
}

пример со неименувани клучеви c Имајте предвид дека првата вредност од n specifier.

Види Исто така

  • pack() - Спакувај податоци во бинарна низа

Белешки од корисници — Интерпретира стринг од XML во објект

randolphothegreat at yahoo dot com
пред 9 години
A helper class to convert integer to binary strings and vice versa. Useful for writing and reading integers to / from files or sockets.

<?php

    class int_helper
    {
        public static function int8($i) {
            return is_int($i) ? pack("c", $i) : unpack("c", $i)[1];
        }

        public static function uInt8($i) {
            return is_int($i) ? pack("C", $i) : unpack("C", $i)[1];
        }

        public static function int16($i) {
            return is_int($i) ? pack("s", $i) : unpack("s", $i)[1];
        }

        public static function uInt16($i, $endianness=false) {
            $f = is_int($i) ? "pack" : "unpack";

            if ($endianness === true) {  // big-endian
                $i = $f("n", $i);
            }
            else if ($endianness === false) {  // little-endian
                $i = $f("v", $i);
            }
            else if ($endianness === null) {  // machine byte order
                $i = $f("S", $i);
            }

            return is_array($i) ? $i[1] : $i;
        }

        public static function int32($i) {
            return is_int($i) ? pack("l", $i) : unpack("l", $i)[1];
        }

        public static function uInt32($i, $endianness=false) {
            $f = is_int($i) ? "pack" : "unpack";

            if ($endianness === true) {  // big-endian
                $i = $f("N", $i);
            }
            else if ($endianness === false) {  // little-endian
                $i = $f("V", $i);
            }
            else if ($endianness === null) {  // machine byte order
                $i = $f("L", $i);
            }

            return is_array($i) ? $i[1] : $i;
        }

        public static function int64($i) {
            return is_int($i) ? pack("q", $i) : unpack("q", $i)[1];
        }

        public static function uInt64($i, $endianness=false) {
            $f = is_int($i) ? "pack" : "unpack";

            if ($endianness === true) {  // big-endian
                $i = $f("J", $i);
            }
            else if ($endianness === false) {  // little-endian
                $i = $f("P", $i);
            }
            else if ($endianness === null) {  // machine byte order
                $i = $f("Q", $i);
            }

            return is_array($i) ? $i[1] : $i;
        }
    }
?>

Usage example:
<?php
    Header("Content-Type: text/plain");
    include("int_helper.php");

    echo int_helper::uInt8(0x6b) . PHP_EOL;  // k
    echo int_helper::uInt8(107) . PHP_EOL;  // k
    echo int_helper::uInt8("\x6b") . PHP_EOL . PHP_EOL;  // 107

    echo int_helper::uInt16(4101) . PHP_EOL;  // \x05\x10
    echo int_helper::uInt16("\x05\x10") . PHP_EOL;  // 4101
    echo int_helper::uInt16("\x05\x10", true) . PHP_EOL . PHP_EOL;  // 1296

    echo int_helper::uInt32(2147483647) . PHP_EOL;  // \xff\xff\xff\x7f
    echo int_helper::uInt32("\xff\xff\xff\x7f") . PHP_EOL . PHP_EOL;  // 2147483647

    // Note: Test this with 64-bit build of PHP
    echo int_helper::uInt64(9223372036854775807) . PHP_EOL;  // \xff\xff\xff\xff\xff\xff\xff\x7f
    echo int_helper::uInt64("\xff\xff\xff\xff\xff\xff\xff\x7f") . PHP_EOL . PHP_EOL;  // 9223372036854775807

?>
jjfoerch на earthlink dot net
21 години пред
I had a situation where I had to unpack a file filled with little-endian order double-floats in a way that would work on either little-endian or big-endian machines.  PHP doesn't have a formatting code that will change the byte order of doubles, so I wrote this workaround.

<?php
/*The following code is a workaround for php's unpack function
which does not have the capability of unpacking double precision
floats that were packed in the opposite byte order of the current
machine.
*/
function big_endian_unpack ($format, $data) {
    $ar = unpack ($format, $data);
    $vals = array_values ($ar);
    $f = explode ('/', $format);
    $i = 0;
    foreach ($f as $f_k => $f_v) {
    $repeater = intval (substr ($f_v, 1));
    if ($repeater == 0) $repeater = 1;
    if ($f_v{1} == '*')
    {
        $repeater = count ($ar) - $i;
    }
    if ($f_v{0} != 'd') { $i += $repeater; continue; }
    $j = $i + $repeater;
    for ($a = $i; $a < $j; ++$a)
    {
        $p = pack ('d',$vals[$i]);
        $p = strrev ($p);
        list ($vals[$i]) = array_values (unpack ('d1d', $p));
        ++$i;
    }
    }
    $a = 0;
    foreach ($ar as $ar_k => $ar_v) {
    $ar[$ar_k] = $vals[$a];
    ++$a;
    }
    return $ar;
}

list ($endiantest) = array_values (unpack ('L1L', pack ('V',1)));
if ($endiantest != 1) define ('BIG_ENDIAN_MACHINE',1);
if (defined ('BIG_ENDIAN_MACHINE')) $unpack_workaround = 'big_endian_unpack';
else $unpack_workaround = 'unpack';
?>

This workaround is used like this:

<?php

function foo() {
        global $unpack_workaround;
    $bar = $unpack_workaround('N7N/V2V/d8d',$my_data);
//...
}

?>

On a little endian machine, $unpack_workaround will simply point to the function unpack.  On a big endian machine, it will call the workaround function.

Note, this solution only works for doubles.  In my project I had no need to check for single precision floats.
Sergio Santana: ssantana на tlaloc dot imta dot mx
21 години пред
This is about the last example of my previous post. For the sake of clarity, I'm including again here the example, which expands the one given in the formal documentation:

<?
  $binarydata = "AA\0A";
  $array = unpack("c2chars/nint", $binarydata);
  foreach ($array as $key => $value)
     echo "\$array[$key] = $value <br>\n";
?>

This outputs:

$array[chars1] = 65 
$array[chars2] = 65 
$array[int] = 65 

Here, we assume that the ascii code for character 'A' is decimal 65.

Remebering that the format string structure is:
<format-code> [<count>] [<array-key>] [/ ...],
in this example, the format string instructs the function to
  1. ("c2...") Read two chars from the second argument ("AA ...), 
  2. (...chars...) Use the array-keys "chars1", and "chars2" for 
      these two chars read,
  3. (.../n...) Read a short int from the second argument (...\0A"),
  4. (...int") Use the word "int" as the array key for the just read
      short.

I hope this is clearer now,

Sergio.
kennwhite dot nospam на hotmail dot com
21 години пред
If having a zero-based index is useful/necessary, then instead of:

$int_list = unpack("s*", $some_binary_data);

 try:

$int_list = array_merge(unpack("s*", $some_binary_data));

This will return a 0-based array:

$int_list[0] = x
$int_list[1] = y
$int_list[2] = z
...

rather than the default 1-based array returned from unpack when no key is supplied:

$int_list[1] = x
$int_list[2] = y
$int_list[3] = z
...

It's not used often, but array_merge() with only one parameter will compress a sequentially-ordered numeric-index, starting with an index of [0].
Sergio Santana: ssantana на tlaloc dot imta dot mx
21 години пред
Suppose we need to get some kind of internal representation of an integer, say 65, as a four-byte long. Then we use, something like:

<?
  $i = 65;
  $s = pack("l", $i); // long 32 bit, machine byte order
  echo strlen($s) . "<br>\n";
  echo "***$s***<br>\n";
?>

The output is:

X-Powered-By: PHP/4.1.2
Content-type: text/html

4
***A*** 

(That is the string "A\0\0\0")

Now we want to go back from string "A\0\0\0" to number 65. In this case we can use:

<?
  $s = "A\0\0\0"; // This string is the bytes representation of number 65
  $arr = unpack("l", $s);
  foreach ($arr as $key => $value)
     echo "\$arr[$key] = $value<br>\n";
?>

And this outpus:
X-Powered-By: PHP/4.1.2
Content-type: text/html

$arr[] = 65

Let's give the array key a name, say "mykey". In this case, we can use: 

<?
  $s = "A\0\0\0"; // This string is the bytes representation of number  65
  $arr = unpack("lmykey", $s);
  foreach ($arr as $key => $value)
     echo "\$arr[$key] = $value\n";
?>

An this outpus:
X-Powered-By: PHP/4.1.2
Content-type: text/html

$arr[mykey] = 65

The "unpack" documentation is a little bit confusing. I think a more complete example could be:

<?
  $binarydata = "AA\0A";
  $array = unpack("c2chars/nint", $binarydata);
  foreach ($array as $key => $value)
    echo "\$array[$key] = $value <br>\n";
?>

whose output is:

X-Powered-By: PHP/4.1.2
Content-type: text/html

$array[chars1] = 65 <br>
$array[chars2] = 65 <br>
$array[int] = 65 <br>

Note that the format string is something like
<format-code> [<count>] [<array-key>] [/ ...]

I hope this clarifies something

Sergio
Анонимен
пред 16 години
Functions I found useful when dealing with fixed width file processing, related to unpack/pack functions.
<?php
/**
* funpack
* format: array of key, length pairs
* data: string to unpack
*/
function funpack($format, $data){
    foreach ($format as $key => $len) {
        $result[$key] = trim(substr($data, $pos, $len));
        $pos+= $len;
    }
    return $result;
}

/**
* fpack
* format: array of key, length pairs
* data: array of key, value pairs to pack
* pad: padding direction
*/
function fpack($format, $data, $pad = STR_PAD_RIGHT){
    foreach ($format as $key => $len){
        $result .= substr(str_pad($data[$key], $len, $pad), 0, $len);
    }
    return $result;
}
?>
billynoah at gmail dot com
1 месец пред
It's with much frustration that I learned, that data packed with "Z" cannot be unpacked again. The unpack() function cannot read back a NUL-terminated string. For example, this simply doesn't work as one expects:

var_dump(unpack('ZZ', "Hello\x00World\x00"));

Produces:

array(1) {
  ["Z"]=>
  string(1) "H"
}

(And no, "Z*" won't help here. I'm not even sure what "Z" is useful for at this point.)
ludwig на kni-online dot de
пред 6 години
Don't forget to decode user-defined-pseudo-byte-sequences before unpacking...
<?php
  $byte_code_string =  '00004040';
  var_dump ( unpack ( 'f', $byte_code_string ) );
?>
Result:
  array(1) {
    [1]=>
    float(6.4096905560973E-10)
  }

whereas
<?php
   $byte_code_string =  '00004040';
   var_dump ( unpack ( 'f', hex2bin ( $byte_code_string ) ) );
?>
Result:
  array(1) {
    [1]=>
    float(3)
  }
Анонимен кукавец
пред 17 години
Warning: This unpack function makes the array with keys starting at 1 instead of starting at 0.

For example:
<?php
 function read_field($h) {
  $a=unpack("V",fread($h,4));
  return fread($h,$a[1]);
 }
?>
norwood на computer dot org
пред 15 години
Reading a text cell from an Excel spreadsheet returned a string with low-order embedded nulls: 0x4100 0x4200 etc. To remove the nulls, used

<?php
$strWithoutNulls = implode( '', explode( "\0", $strWithNulls ) );
?>

(unpack() didn't seem to help much here; needed chars back to re-constitute the string, not integers.)
Арон Велс
пред 15 години
Another option for converting binary data into PHP data types, is to use the Zend Framework's Zend_Io_Reader class:
http://bit.ly/9zAhgz

There's also a Zend_Io_Writer class that does the reverse.
googlybash24 на aol dot com
пред 13 години
To convert big endian to little endian or to convert little endian to big endian, use the following approach as an example:

<?php
// file_get_contents() returns a binary value, unpack("V*", _ ) returns an unsigned long 32-bit little endian decimal value, but bin2hex() after that would just give the hex data in the file if alone, so instead we use:
// file_get_contents(), unpack("V*", _ ), then dechex(), in that order, to get the byte-swapping effect.
?>

With the logic of the approach in this example, you can discover how to swap the endian byte order as you need.
rogier
пред 14 години
be aware of the behavior of your system that PHP resides on.

On x86, unpack MAY not yield the result you expect for UInt32

This is due to the internal nature of PHP, being that integers are internally stored as SIGNED!

For x86 systems, unpack('N', "\xff\xff\xff\xff") results in -1
For (most?) x64 systems, unpack('N', "\xff\xff\xff\xff") results in 4294967295.

This can be verified by checking the value of PHP_INT_SIZE.
If this value is 4, you have a PHP that internally stores 32-bit.
A value of 8 internally stores 64-bit.

To work around this 'problem', you can use the following code to avoid problems with unpack.
The code is for big endian order but can easily be adjusted for little endian order (also, similar code works for 64-bit integers):

<?php
function _uint32be($bin)
{
    // $bin is the binary 32-bit BE string that represents the integer
    if (PHP_INT_SIZE <= 4){
        list(,$h,$l) = unpack('n*', $bin);
        return ($l + ($h*0x010000));
    }
    else{
        list(,$int) = unpack('N', $bin);
        return $int;
    }
}
?>

Do note that you *could* also use sprintf('%u', $x) to show the unsigned real value.
Also note that (at least when PHP_INT_SIZE = 4) the result WILL be a float value when the input is larger then 0x7fffffff (just check with gettype);

Hope this helps people.
sica на wnet com br
пред 16 години
The script following is a example how to save more than one values on file separating its with "\r\n" and how to recovering its values.

<?php
// Save two integer values in a binary file
$nomearq = "./teste.bin";
$valor = 123;
$ptrarq = fopen($nomearq, "wb");
$valorBin = pack("L",$valor);
echo "First value ($valor) packed with ";
echo fwrite($ptrarq, $valorBin)." bytes<br>";
echo "Separator \\r\\n with ";
echo fwrite($ptrarq, "\r\n")." bytes<br>";
$valor = 456;
$valorBin = pack("L",$valor);
echo "Second value ($valor) packed with ";
echo fwrite($ptrarq, $valorBin)." bytes<br>";
fclose($ptrarq);

// Recover the saved values
$ptrarq = fopen($nomearq, "rb");
$valorBin = file($nomearq,filesize($nomearq));
echo "<br>The reading values is:<br>";
foreach($valorBin as $valor){
  $valor = unpack("L",$valor);
  print_r($valor);
  echo "<br>";
}
fclose($ptrarq);
?>

Results:
First value (123) packed with 4 bytes
Separator \r\n with 2 bytes
Second value (456) packed with 4 bytes

The reading values is:
Array ( [1] => 123 ) 
Array ( [1] => 456 )
iredden на redden dot on dot ca
ian at eiloart dot com
<?php

function parse_pascalstr($bytes_parsed, $parse_str) { 
    $parse_info = unpack("x$bytes_parsed/cstr_len", $parse_str);
    $str_len = $parse_info["str_len"]; 
    $bytes_parsed = $bytes_parsed + 1; 
    $parse_info = unpack("x$bytes_parsed/A".$str_len."str", $parse_str); 
    $str = $parse_info["str"]; 
    $bytes_parsed = $bytes_parsed + strlen($str); 

    return array($str, $bytes_parsed); 
}

?>
На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.