Start · Sprachen · PHP · Referenz · unpack

unpack

Funktion

Entpackt binäre Daten aus einer Zeichenkette anhand eines Format-Codes und gibt ein assoziatives Array zurück.

seit PHP 4.0.0 Kategorie: misc

Signatur

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

Beschreibung

unpack() ist das Gegenstück zu pack() und liest rohe Binärdaten aus einer Zeichenkette aus. Das Ergebnis ist ein Array, dessen Schlüssel durch die im Format-String angegebenen Namen bestimmt werden. Typische Einsatzgebiete sind das Lesen von Binärprotokollen (z. B. Netzwerkpakete, Dateiheader wie BMP, WAV oder ZIP), die Kommunikation mit C-Bibliotheken sowie das Parsen von seriellen Datenströmen.

Der Format-String besteht aus einem oder mehreren Format-Codes, optional gefolgt von einer Wiederholungsanzahl und einem Schrägstrich (/) sowie einem beliebigen Namen: z. B. 'N1länge/A10name'. Häufig verwendete Codes sind unter anderem: a (Byte-String), A (String mit Leerzeichen-Trim), c/C (vorzeichenbehaftetes/vorzeichenloses Byte), n/N (unsigned short/long Big-Endian), v/V (unsigned short/long Little-Endian), f/d (float/double) sowie H/h (Hex-String).

Ab PHP 7.1.0 kann ein optionaler $offset-Parameter angegeben werden, mit dem das Entpacken an einer bestimmten Byte-Position in der Eingabezeichenkette beginnt – praktisch für das schrittweise Parsen größerer Binärstrukturen.

Wichtig: Im Gegensatz zu Perl beginnt das Array bei PHP mit Index 1, wenn kein expliziter Name vergeben wird. Werden mehrere Felder desselben Namens definiert, überschreiben sich die Werte gegenseitig – daher sollten alle Felder mit eindeutigen Namen versehen werden.

Parameter

Name Typ Default Beschreibung
$format Pflicht string Format-Zeichenkette, die festlegt, wie die Binärdaten zu interpretieren sind. Jeder Eintrag hat die Form Typ[Anzahl]Name, mehrere Einträge werden durch / getrennt. Beispiel: 'Nid/A10name'.
$string Pflicht string Die binäre Eingabezeichenkette, aus der die Daten entpackt werden sollen – z. B. der Inhalt einer Binärdatei oder die Antwort eines Netzwerkprotokolls.
$offset int 0 Byte-Offset, ab dem in $string mit dem Entpacken begonnen wird. Seit PHP 7.1.0 verfügbar.

Rückgabewert

Typ
array|false
Beschreibung
Gibt ein assoziatives Array zurück, dessen Schlüssel den im Format-String angegebenen Namen entsprechen. Bei Feldern ohne Namen werden aufsteigende Integer-Indizes ab 1 verwendet. Im Fehlerfall (z. B. ungültiger Format-String oder Eingabe zu kurz) wird false zurückgegeben.

Beispiele

WAV-Dateiheader parsen

<?php
// Einfaches Parsen der ersten 12 Bytes eines WAV-Headers
$fp = fopen('beispiel.wav', 'rb');
$header = fread($fp, 12);
fclose($fp);

$daten = unpack('A4chunkId/Vchunksize/A4format', $header);

echo 'Chunk-ID:   ' . $daten['chunkId']   . "\n"; // RIFF
echo 'Chunk-Size: ' . $daten['chunksize'] . " Bytes\n";
echo 'Format:     ' . $daten['format']    . "\n"; // WAVE
Chunk-ID: RIFF Chunk-Size: 1234567 Bytes Format: WAVE

Netzwerkpaket mit mehreren Feldern entpacken

<?php
// Simuliertes Binärpaket: 1 Byte Typ, 2 Bytes Länge (Big-Endian), 4 Bytes ID (Big-Endian)
$paket = pack('CnN', 3, 256, 42000);

$felder = unpack('Ctyp/nlänge/Nid', $paket);

echo 'Typ:   ' . $felder['typ']    . "\n"; // 3
echo 'Länge: ' . $felder['länge'] . "\n"; // 256
echo 'ID:    ' . $felder['id']    . "\n"; // 42000
Typ: 3 Länge: 256 ID: 42000

Offset-Parameter nutzen (ab PHP 7.1)

<?php
// 4 Bytes Präfix überspringen, dann eine 32-Bit-Zahl lesen
$data = pack('A4N', 'SKIP', 99999);

$result = unpack('Nwert', $data, 4);
echo 'Wert: ' . $result['wert'] . "\n"; // 99999
Wert: 99999

// Wichtig · Fallstricke

Fallstricke:

  • Werden zwei Felder mit demselben Namen definiert, überschreibt das zweite Feld das erste, ohne eine Warnung auszulösen – stets eindeutige Namen vergeben.
  • Die Byte-Reihenfolge (Big-Endian vs. Little-Endian) muss exakt mit dem Quellformat übereinstimmen. Für maschinennative Byte-Reihenfolge stehen l/L (signed/unsigned long) und ähnliche Codes bereit.
  • Bei der Verwendung mit Netzwerkprotokollen immer prüfen, ob die Eingabezeichenkette lang genug ist, um Buffer-Underflows zu vermeiden.
  • Das Ergebnis-Array beginnt bei PHP bei Index 1, wenn kein Name vergeben wird (anders als in Perl).
  • Sicherheitshinweis: Entpacke niemals unkontrollierte externe Binärdaten ohne vorherige Längenprüfung, da zu kurze Eingaben zu unerwartetem Verhalten führen können.

Siehe auch