Aktueller Standort: Startseite> Neueste Artikel> pack () die falschen Daten erhält? Vielleicht ist das Format von pack () falsch

pack () die falschen Daten erhält? Vielleicht ist das Format von pack () falsch

M66 2025-05-28

Bei der Verarbeitung von Binärdaten in PHP sind Pack () und pack () leistungsstarke Funktionspaare, die Daten in binäre Zeichenfolgen umwandeln oder Originalwerte von ihnen analysieren können. Viele Entwickler stoßen jedoch häufig auf ein häufiges Problem bei der Verwendung dieser beiden Funktionen: Daten, die mit Pack () verpackt sind, erscheint beim Auspacken mit auspack () verstümmelt oder ausgenommen. Diese Situation wird hauptsächlich durch Fehlschreibe -Format -Saiten verursacht.

Ein gemeinsames "verstümmeltes" Szenario

Angenommen, Sie haben eine Ganzzahl und eine Zeichenfolge und möchten sie in einen binären Datenspeicher oder eine Übertragung packen und dann auspacken und abrufen:

 $data = pack('N/A4', 12345678, 'test');

Viele Leute denken vielleicht, dass der obige Code eine Ganzzahl 12345678 und einen String 'Test' richtig verpackt. Bei der Ausführung werden Sie jedoch feststellen, dass die durch pack () gelösten Daten nicht so sind, wie Sie möchten:

 $unpacked = unpack('Nnum/A4str', $data);
print_r($unpacked);

Die Ausgabe kann leer, verstümmelt oder sogar Warnung auslösen.

Grund? Die Formatzeichenfolge ist falsch geschrieben.

Wenn die Formatzeichenfolge nicht korrekt ist, wird der Fehler gelöst!

Die Formatketten von pack () und pack () müssen nicht nur in Ordnung, sondern auch in Länge, Größe und Typ übereinstimmen.

Lassen Sie uns das obige Fehlerbeispiel sorgfältig analysieren:

 $data = pack('N/A4', 12345678, 'test');

Diese Formatkette ist eigentlich nicht legal. Weil N einen 4-Byte-Long (Big-Endian) darstellt, aber / ist ein illegaler Charakter (es hat in diesem Zusammenhang keine Bedeutung). Der wahre Weg, es zu schreiben, sollte sein:

 $data = pack('Na4', 12345678, 'test');

Beim Auspacken müssen Sie auch das Format streng ausrichten:

 $unpacked = unpack('Nnum/a4str', $data);

Zu diesem Zeitpunkt erwarten wir die Ausgabe:

 Array
(
    [num] => 12345678
    [str] => test
)

Beachten Sie einen subtilen Unterschied:

  • A4 bedeutet "eine Schnur mit leeren Bytes", unabhängig davon, ob die Saite so lang ist oder nicht;

  • A4 bedeutet "eine mit Leerzeichen gefüllte Schnur", und der Raum am Ende wird ignoriert.

  • n bedeutet 2 Byte nicht signiert kurz (Big Endian);

  • V bedeutet 2 Byte nicht signiert kurz (Little Endian);

  • N bedeutet 4 Bytes unsigniert lang (Big Endian);

  • V repräsentiert 4 Bytes, die nicht signiert (kleiner Endian);

Wenn Sie den falschen Brief verwenden, ist das Ergebnis möglicherweise völlig falsch.

Byte -Ausrichtung: Lassen Sie sich nicht die Struktur erraten

Wenn Sie sich mit plattformübergreifenden Datenstrukturen oder binären Protokollen befassen (z.

Definieren Sie beispielsweise eine Paketstruktur wie folgt:

  • 2 Byte -Versionsnummer (UINT16)

  • 4 Byte Timestamp (uint32)

  • 8 Byte -Benutzer -ID (UINT64)

  • 20 Byte Benutzername (String)

Kann geschrieben werden als:

 $data = pack('nNVa20', 1, time(), 123456789, 'hello');

Das entsprechende Auspacken muss genau gleich sein:

 $unpacked = unpack('nversion/Ntime/Vuid/a20username', $data);

Aber Hinweis: Verwechseln Sie nicht die Reihenfolge von V und N ! Wenn der Server die C-Sprachstruktur verwendet, um zu definieren, dass die Byte-Reihenfolge Big-Endian ist, Sie aber V (Little-Endian) zum Lesen verwenden, dann ist die Lösung falsch.

Vorschläge: Strukturkonstanten definieren und einheitlich halten

Um Format -Zeichenfolgenfehler zu vermeiden, wird empfohlen, Strukturdefinitionen in Konstanten oder klar kommentierte Funktionen für eine einfache Wartung und Zusammenarbeit einzudämmen. Zum Beispiel:

 define('USER_STRUCT_FORMAT', 'nversion/Ntime/Vuid/a20username');

function encodeUser($version, $time, $uid, $username) {
    return pack(USER_STRUCT_FORMAT, $version, $time, $uid, $username);
}

function decodeUser($binary) {
    return unpack(USER_STRUCT_FORMAT, $binary);
}

Dies kann Fehler vermeiden, die durch manuelle Rechtschreibformat -Saiten an mehreren Stellen verursacht werden, und erleichtern auch die Dokumentsynchronisation.

Zusammenfassung

Die Verwendung von pack () und pack () ist eine Standardmethode, um binäre Daten in PHP zu verarbeiten, aber die Anforderungen für Formatketten sind sehr streng. Das Auspacken von verstümmelten Code ist die meiste Zeit kein Funktionsproblem, sondern ein Missverhältnis in Formaten. Denken Sie daran:

  • Die Bedeutung und Anzahl der Bytes jedes Formatsymbols;

  • Die Reihenfolge der kleinen und der Enden kann nicht verwechselt werden;

  • Die Auftrags- und Verpackungsreihenfolge muss konsistent sein.

  • Die Länge der Zeichenfolge muss festgelegt oder klar angegeben werden.

  • Es wird empfohlen, dass die Strukturverpackung für eine einfache Wiederverwendung vereinheitlicht wird.

Wenn Sie das nächste Mal aufpack () verstümmelten Code begegnen, beeilen Sie sich nicht, um an den Daten zu zweifeln. Überprüfen Sie zunächst, ob Ihre Format -Zeichenfolge korrekt geschrieben ist.