Signatur
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
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
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
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
// 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.