W3docs

pack()

Dieser Artikel erklärt die PHP-Funktion pack(): Funktionsweise, Formatstrings, Byte-Reihenfolge und praktische Anwendungsbeispiele.

Dieser Artikel behandelt PHPs pack()-Funktion: was sie tut, die Formatstring-Minisprache, die sie verwendet, wie die Byte-Reihenfolge (Endianness) das Ergebnis beeinflusst, und praktische Beispiele — einschließlich des Rückwegs mit unpack().

Was pack() macht

pack() nimmt gewöhnliche PHP-Werte (Integer, Floats, Strings) und legt sie byteweise in einem einzelnen Binär-String ab — einem String, dessen Zeichen rohe Bytes statt lesbarem Text sind.

pack(string $format, mixed ...$values): string
  • $format — ein kompakter Formatstring, der der Reihe nach beschreibt, wie jeder Wert kodiert werden soll (Typ, Größe und Byte-Reihenfolge).
  • ...$values — ein oder mehrere zu kodierende Werte, die von links nach rechts den Formatcodes zugeordnet werden.

Der Rückgabewert ist ein Binär-String. Da diese Bytes meist nicht druckbar sind, werden die Ergebnisse in den Beispielen unten durch bin2hex() geleitet, damit man genau sehen kann, welche Bytes erzeugt wurden (zwei Hex-Ziffern = ein Byte).

Wann verwendet man es?

pack() kommt zum Einsatz, wenn PHP ein Format sprechen muss, das in rohen Bytes statt in Text definiert ist:

  • Binäre Protokolle — Netzwerkpakete aufbauen, bei denen ein Header aus „2 Bytes Länge gefolgt von einer 4-Byte-ID" besteht.
  • Binäre Dateiformate — PNG-Chunks, WAV-Header oder beliebige Layouts mit fest breiten Feldern schreiben.
  • Hashing/Crypto-Helfer — einen Hex-Digest in seine rohe Byte-Form umwandeln, um ihn an hash_hmac() oder openssl_* zu übergeben.
  • Kommunikation mit C/Embedded-Systemen, die fest dimensionierte Felder mit bestimmter Endianness erwarten.

Für die reine PHP-zu-PHP-Speicherung sind serialize() oder json_encode() benutzerfreundlicher; pack() glänzt, wenn das Byte-Layout selbst wichtig ist.

Ein erstes Beispiel

php— editable, runs on the server

123 in Hexadezimal ist 0x7b. Der Formatcode N bedeutet „unsigned long (4 Bytes), Network Byte Order", daher wird der Wert auf vier Bytes aufgefüllt und mit dem höchstwertigsten Byte zuerst geschrieben: 00 00 00 7b.

Den Formatstring lesen

Ein Formatstring ist eine Folge von Formatcodes, denen optional eine Wiederholungsanzahl folgt:

N    one unsigned long
N4   four unsigned longs in a row
N*   as many unsigned longs as there are remaining values
A10  a 10-character space-padded string

Codes können verkettet werden, um einen ganzen Datensatz zu beschreiben. Die übergebenen Werte müssen der Reihe nach mit den Codes übereinstimmen:

<?php
// A 2-byte short (1) followed by a 4-byte long (16909060)
$header = pack('nN', 1, 16909060);

echo bin2hex($header); // 000101020304
?>

Hier erzeugt n das Ergebnis 00 01 (der Short 1) und N produziert 01 02 03 04 (der Long 16909060, also 0x01020304). Die Bytes erscheinen genau in der Reihenfolge, in der die Codes geschrieben wurden.

Byte-Reihenfolge (Endianness)

Dieselbe Zahl kann mit ihren Bytes in zwei entgegengesetzten Reihenfolgen gespeichert werden, und pack() bietet für jede einen eigenen Code:

  • Big-Endian (auch bekannt als Network Byte Order) speichert das höchstwertige Byte zuerst — Codes n (Short) und N (Long).
  • Little-Endian speichert das niederwertigste Byte zuerst — Codes v (Short) und V (Long).
<?php
echo bin2hex(pack('N', 1)), "\n"; // 00000001  (big-endian)
echo bin2hex(pack('V', 1)), "\n"; // 01000000  (little-endian)
?>

Das ist wichtig, weil der Empfänger dieselbe Konvention verwenden muss, um die Daten wieder zu lesen. Netzwerkprotokolle standardisieren auf Big-Endian (N/n); viele Dateiformate (und x86-Speicher-Dumps) verwenden Little-Endian (V/v). Im Zweifelsfall N/n für den Datenaustausch wählen — das ist die Garantie von „Network Byte Order".

Häufige Formatcodes

Eine Auswahl der am häufigsten verwendeten Codes (die vollständige Liste findet sich im PHP-Handbuch):

CodeBedeutung
aNUL-aufgefüllter String
ALeerzeichen-aufgefüllter String
c / CVorzeichenbehaftetes / vorzeichenloses Char (1 Byte)
s / SVorzeichenbehafteter / vorzeichenloser Short, native Byte-Reihenfolge (2 Bytes)
n / NVorzeichenloser Short / Long, Big-Endian
v / VVorzeichenloser Short / Long, Little-Endian
f / dFloat / Double, Maschinenformat
H / hHex-String, hohes / niedriges Nibble zuerst

String-Codes verwenden die Wiederholungsanzahl als Feldbreite, nicht als Werteanzahl:

<?php
echo pack('A6', 'PHP'), "|"; // PHP   |  (padded to 6 chars with spaces)
?>

Hin und zurück: pack() und unpack()

pack() schreibt Bytes; unpack() liest sie zurück in PHP-Werte. Um die ursprünglichen Daten wiederherzustellen, muss dasselbe Layout beschrieben werden, und unpack() benötigt zusätzlich einen Namen für jedes Feld:

<?php
// Encode two fields
$binary = pack('Nn', 65536, 7);

// Decode using the same layout, naming each field
$values = unpack('Nfirst/nsecond', $binary);

echo $values['first'], ' ', $values['second']; // 65536 7
?>

Der Schrägstrich (/) trennt benannte Felder im unpack()-Format. Wenn die Layouts auf beiden Seiten nicht übereinstimmen, erhält man unleserliche Daten — Kodierung und Dekodierung sind eng gekoppelt.

Fallstricke

  • Codes und Werte müssen übereinstimmen. Werden weniger Werte als Codes übergeben, wird eine Warnung ausgelöst und false zurückgegeben; zusätzliche Werte werden stillschweigend ignoriert (es sei denn, * wurde verwendet).
  • Integer-Überlauf wird abgeschnitten, nicht gemeldet. pack('C', 300) behält nur das niedrige Byte (300 & 0xFF = 44) statt einen Fehler auszulösen — Bereiche selbst validieren.
  • Native Codes (s, S, i, l, Floats) sind nicht portabel. Ihre Größe und Byte-Reihenfolge hängen von der Plattform ab. Für Daten, die zwischen Maschinen ausgetauscht werden, die expliziten Big-/Little-Endian-Codes bevorzugen.
  • Das Ergebnis ist ein Binär-String. Nicht per echo auf einer HTML-Seite ausgeben oder als Text vergleichen; mit bin2hex() untersuchen oder in eine Binärdatei/einen Stream schreiben.

Für die umgekehrte Operation geht es weiter mit dem unpack()-Kapitel. Um die rohen Bytes in eigenen Experimenten sichtbar zu machen, ist der auf dieser Seite verwendete bin2hex()-Helfer unverzichtbar.

Fazit

pack() wandelt PHP-Werte in einen präzise kontrollierten Binär-String um, mit einer kompakten Format-Minisprache für Feldtyp, Größe und Byte-Reihenfolge. Es kommt zum Einsatz, wann immer Bytes erzeugt werden müssen, die ein anderes System nach seinen eigenen Regeln liest — Binärprotokolle, Dateiformate oder Krypto-Routinen — und wird mit unpack() kombiniert, um die Daten wieder zu lesen.

Übungen

Übung
Was macht die Funktion pack() in PHP?
Was macht die Funktion pack() in PHP?
Was this page helpful?