W3docs

pack()

Neste artigo, abordamos a função pack() do PHP: visão geral, funcionamento e exemplos práticos de uso.

Este artigo aborda a função pack() do PHP: o que ela faz, a mini-linguagem de strings de formato que utiliza, como a ordem dos bytes (endianness) afeta o resultado e exemplos práticos que você pode executar — incluindo o ciclo de volta com unpack().

O que pack() faz

pack() recebe valores PHP comuns (inteiros, floats, strings) e os organiza byte a byte em uma única string binária — uma string cujos caracteres são bytes brutos em vez de texto legível.

pack(string $format, mixed ...$values): string
  • $format — uma string de formato compacta que descreve, em ordem, como cada valor deve ser codificado (seu tipo, tamanho e ordem de bytes).
  • ...$values — um ou mais valores a codificar, associados da esquerda para a direita com os códigos de formato.

O valor de retorno é uma string binária. Como esses bytes geralmente não são imprimíveis, os exemplos abaixo passam o resultado por bin2hex() para que você possa ver exatamente quais bytes foram produzidos (dois dígitos hexadecimais = um byte).

Quando você usaria isso?

Você recorre a pack() sempre que o PHP precisa falar um formato definido em bytes brutos em vez de texto:

  • Protocolos binários — construção de pacotes de rede onde um cabeçalho é "um comprimento de 2 bytes seguido de um id de 4 bytes."
  • Formatos de arquivo binários — escrita de chunks PNG, cabeçalhos WAV ou qualquer layout com campos de largura fixa.
  • Auxiliares de hashing/criptografia — conversão de um resumo hexadecimal na sua forma de bytes brutos para passar a hash_hmac() ou openssl_*.
  • Comunicação com sistemas C/embarcados que esperam campos de tamanho fixo e endianness fixo.

Para armazenamento PHP-a-PHP comum, serialize() ou json_encode() são mais amigáveis; pack() brilha quando o layout de bytes em si importa.

Um primeiro exemplo

php— editable, runs on the server

123 em hexadecimal é 0x7b. O código de formato N significa "unsigned long (4 bytes), ordem de bytes de rede," portanto o valor é preenchido com quatro bytes e escrito com o byte mais significativo primeiro: 00 00 00 7b.

Lendo a string de formato

Uma string de formato é uma sequência de códigos de formato, cada um opcionalmente seguido por uma contagem de repetição:

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

Você pode concatenar códigos para descrever um registro inteiro. Os valores que você passa devem se alinhar com os códigos em ordem:

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

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

Aqui n produz 00 01 (o short 1) e N produz 01 02 03 04 (o long 16909060, que é 0x01020304). Os bytes aparecem exatamente na ordem em que os códigos foram escritos.

Ordem de bytes (endianness)

O mesmo número pode ser armazenado com seus bytes em duas ordens opostas, e pack() fornece um código para cada:

  • Big-endian (também conhecido como ordem de bytes de rede) armazena o byte mais significativo primeiro — códigos n (short) e N (long).
  • Little-endian armazena o byte menos significativo primeiro — códigos v (short) e V (long).
<?php
echo bin2hex(pack('N', 1)), "\n"; // 00000001  (big-endian)
echo bin2hex(pack('V', 1)), "\n"; // 01000000  (little-endian)
?>

Isso importa porque o receptor deve usar a mesma convenção para ler os dados de volta. Protocolos de rede padronizam em big-endian (N/n); muitos formatos de arquivo (e dumps de memória x86) usam little-endian (V/v). Na dúvida, escolha N/n para intercâmbio — é isso que "ordem de bytes de rede" garante.

Códigos de formato comuns

Uma seleção dos códigos mais usados (consulte o manual do PHP para a lista completa):

CódigoSignificado
aString preenchida com NUL
AString preenchida com espaço
c / CChar com sinal / sem sinal (1 byte)
s / SShort com sinal / sem sinal, ordem de bytes nativa (2 bytes)
n / NShort / long sem sinal, big-endian
v / VShort / long sem sinal, little-endian
f / dFloat / double, formato da máquina
H / hString hexadecimal, nibble alto / baixo primeiro

Códigos de string usam a contagem de repetição como uma largura de campo, não uma contagem de valores:

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

Ciclo completo: pack() e depois unpack()

pack() escreve bytes; unpack() os lê de volta como valores PHP. Para recuperar os dados originais você deve descrever o mesmo layout, e unpack() adicionalmente precisa de um nome para cada campo:

<?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
?>

A barra (/) separa os campos nomeados no formato de unpack(). Se os layouts dos dois lados não coincidirem, você obtém dados corrompidos — codificação e decodificação estão fortemente acopladas.

Armadilhas

  • Códigos e valores devem se alinhar. Passar menos valores do que códigos dispara um aviso e retorna false; valores extras são silenciosamente ignorados (a menos que você tenha usado *).
  • Overflow de inteiros é truncado, não sinalizado. pack('C', 300) mantém apenas o byte baixo (300 & 0xFF = 44) em vez de gerar um erro — valide os intervalos você mesmo.
  • Códigos nativos (s, S, i, l, floats) não são portáveis. Seu tamanho e ordem de bytes dependem da plataforma. Para dados que cruzam máquinas, prefira os códigos explícitos big-/little-endian.
  • O resultado é uma string binária. Não use echo para exibi-la em uma página HTML nem a compare como texto; inspecione-a com bin2hex() ou escreva-a em um arquivo/stream binário.

Para a operação inversa, continue com o capítulo de unpack(). Para ver os bytes brutos em seus próprios experimentos, o auxiliar bin2hex() usado ao longo desta página é inestimável.

Conclusão

pack() converte valores PHP em uma string binária com controle preciso, com uma mini-linguagem de formato compacta para o tipo de campo, tamanho e ordem de bytes. Use-a sempre que precisar produzir bytes que outro sistema lê em seus próprios termos — protocolos binários, formatos de arquivo ou rotinas criptográficas — e combine-a com unpack() para ler os dados de volta.

Prática

Prática
O que a função pack() em PHP faz?
O que a função pack() em PHP faz?
Was this page helpful?