W3docs

unpack()

Erfahren Sie mehr über die PHP-Funktion unpack(): Syntax, Formatcodes, Byte-Reihenfolge und Praxisbeispiele.

PHP-Strings sind im Grunde Folgen roher Bytes, was sie zu einem natürlichen Behälter für Binärdaten macht — Bild-Header, Netzwerkpakete, Dateiformate und Protokollrahmen. Die Funktion unpack() liest diesen rohen Byte-Strom und wandelt ihn in gewöhnliche PHP-Werte (Ganzzahlen, Fließkommazahlen, Strings) um, mit denen Sie arbeiten können. Dieser Artikel behandelt die Signatur der Funktion, ihre Formatcodes, die Byte-Reihenfolge, häufige Fallstricke und die Verwendung zusammen mit pack().

Syntax

unpack(string $format, string $data, int $offset = 0): array|false
ParameterBeschreibung
$formatEin Formatstring, der beschreibt, wie die Bytes interpretiert werden sollen (Codes sind unten aufgeführt).
$dataDer binäre String, aus dem gelesen wird.
$offsetByteposition, ab der gelesen werden soll (ab PHP 7.1 hinzugefügt). Standardmäßig 0.

Die Funktion gibt ein assoziatives Array der entpackten Werte zurück oder false bei einem Fehler. unpack() ist die Umkehrfunktion von pack(): Welches Layout Sie mit pack() schreiben, lesen Sie mit denselben Formatcodes zurück.

Ein erstes Beispiel

Der Formatstring besteht aus einer oder mehreren Codes. Jeder Code besteht aus einem einzelnen Buchstaben für einen Datentyp, einer optionalen Wiederholungsanzahl und einem optionalen Namen.

php— editable, runs on the server

Hier bedeutet "C*" „lies jeden verbleibenden Byte als vorzeichenloses 8-Bit-Integer". Der Wiederholungszähler * verarbeitet alle verfügbaren Bytes. Wenn Sie keinen Namen angeben, nummeriert unpack() die Ergebnisse ab 1 (nicht 0):

Array
(
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => 5
)

Formatcodes

Jeder Code entspricht einer festen Anzahl von Bytes. Die häufigsten:

CodeTypGröße
C / cVorzeichenloser / vorzeichenbehafteter Char1 Byte
nVorzeichenloser Short, Big-Endian2 Bytes
vVorzeichenloser Short, Little-Endian2 Bytes
S / sVorzeichenloser / vorzeichenbehafteter Short, Maschinenreihenfolge2 Bytes
NVorzeichenloser Long, Big-Endian4 Bytes
VVorzeichenloser Long, Little-Endian4 Bytes
L / lVorzeichenloser / vorzeichenbehafteter Long, Maschinenreihenfolge4 Bytes
f / dFloat / Double, Maschinenreihenfolge4 / 8 Bytes
a / AString (NUL-aufgefüllt / Leerzeichen-aufgefüllt)wie angegeben
H / hHex-String, High / Low Nibble zuerstpro Nibble

Eine Zahl nach einem Code wiederholt ihn (C4 liest vier Chars); ein * liest alle verbleibenden Bytes.

Felder benennen

Echte Binärformate bestehen aus gemischten Feldern, daher gibt man jedem einen Namen und trennt die Codes mit /:

php— editable, runs on the server

"C2chars/Sint/Nlong" liest die ersten beiden Bytes als chars1/chars2, die nächsten zwei als maschinengeordneten Short int und die letzten vier als Big-Endian-Long long:

Array
(
    [chars1] => 1
    [chars2] => 2
    [int] => 1027
    [long] => 84281096
)

Wenn ein Code eine Wiederholungsanzahl und einen Namen hat, hängt unpack() einen Index an den Namen an (chars1, chars2, …), damit die Werte sich nicht überschneiden.

Byte-Reihenfolge ist wichtig

Dieselben vier Bytes bedeuten unterschiedliche Zahlen, je nach Byte-Reihenfolge. N/n sind Big-Endian (Netzwerkreihenfolge); V/v sind Little-Endian (x86-nativ); S/L folgen der Host-Maschine und sind daher nicht portierbar. Für Daten, die zwischen Maschinen ausgetauscht werden — ein Dateiformat oder ein Netzwerkprotokoll — wählen Sie immer einen expliziten Endian-Code, damit das Ergebnis überall gleich ist.

<?php
$bytes = "\x01\x00\x00\x00";
print_r(unpack("Vlittle", $bytes)); // little-endian: 1
print_r(unpack("Nbig", $bytes));    // big-endian: 16777216
?>
Array
(
    [little] => 1
)
Array
(
    [big] => 16777216
)

Hin- und Rückumwandlung mit pack()

Da unpack() das Spiegelbild von pack() ist, können Sie Werte in einen kompakten Binär-Blob serialisieren und sie mit dem passenden Format direkt zurücklesen:

<?php
$packed = pack("nN", 1027, 84281096); // build the bytes
$result = unpack("nshort/Nlong", $packed);
print_r($result);
?>
Array
(
    [short] => 1027
    [long] => 84281096
)

Häufige Fallstricke

  • Schlüssel beginnen bei 1. Unbenannte Ergebnisse sind 1-indiziert, was beim Durchlaufen zu Verwirrung führt. Benennen Sie Ihre Felder oder denken Sie an den Offset.
  • Namen mit Wiederholungsanzahl erhalten ein Indexsuffix (byte1, byte2), sodass unpack("C4byte", ...) byte1byte4 liefert, nicht ein einzelnes byte.
  • Maschinengeordnete Codes (S, L, s, l) sind nicht portierbar. Verwenden Sie n/N oder v/V für alles, was gespeichert oder übertragen wird.
  • false bei zu wenig Daten. Wenn das Format mehr Bytes verlangt, als $data enthält, gibt unpack() false zurück und gibt eine Warnung aus — überprüfen Sie den Rückgabewert, bevor Sie ihn verwenden.

Fazit

Die Funktion unpack() wandelt rohe Bytes mit kompakten Formatcodes in PHP-Werte um und ist die lesende Hälfte des pack()-Paares. Beherrschen Sie die Endian-Codes und die Feldbenennungssyntax, und Sie können nahezu jeden Binärdatei-Header oder Netzwerkrahmen parsen. Um Binärdaten stattdessen in einen lesbaren Hex-String umzuwandeln, siehe bin2hex().

Übungen

Übung
Was macht die PHP-Funktion 'unpack'?
Was macht die PHP-Funktion 'unpack'?
Was this page helpful?