當前位置: 首頁> 最新文章列表> 用pack() 實現二進制數據的序列化

用pack() 實現二進制數據的序列化

M66 2025-06-05

在PHP 中, pack()函數用於將數據按照指定的格式打包成二進製字符串。這在處理網絡傳輸、文件寫入以及與C 語言或其他低級語言交互時非常有用。本文將詳細講解pack()函數的用法,並結合實例說明如何將數據打包成二進制格式。

pack() 函數簡介

pack()的基本語法如下:

 string pack(string $format, mixed $values, mixed ...$values)
  • $format :指定數據的格式,由一個或多個格式代碼組成。

  • $values :要打包的值,可以是多個參數。

返回值是一個按指定格式打包後的二進製字符串。

常用格式代碼

格式代碼描述示例
a NUL 字符填充的字符串pack('a4', 'abc')
A空格填充的字符串pack('A4', 'abc')
c有符號字符(1 字節) pack('c', 65)
C無符號字符(1 字節) pack('C', 65)
s有符號短整數(2 字節) pack('s', 1234)
S無符號短整數(2 字節) pack('S', 1234)
i有符號整型(機器字長) pack('i', 123456)
I無符號整型(機器字長) pack('I', 123456)
l有符號長整數(4 字節) pack('l', 123456)
L無符號長整數(4 字節) pack('L', 123456)
f浮點數(4 字節) pack('f', 3.14)
d雙精度浮點數(8 字節) pack('d', 3.14)
n無符號短整數(16位大端字節序) pack('n', 1234)
N無符號長整數(32位大端字節序) pack('N', 1234)

例子解析

1. 打包字符串與整數

<?php
// 打包一個長度為4的字符串和一個32位無符號大端整數
$packed = pack('a4N', 'test', 123456789);
echo bin2hex($packed);
?>

這裡'a4'表示打包一個長度為4 的字符串,不足部分以NUL 字符填充; 'N'表示打包一個32 位無符號大端整數。 bin2hex()將二進制內容轉換成16進制便於查看。

2. 使用pack() 構建網絡協議包

假設你需要構造一個簡易的網絡數據包,包含命令類型(1字節)和數據長度(4字節大端),然後是數據體:

 <?php
$command = 1;               // 命令類型,1位元組
$data = "Hello, m66.net!";  // 數據體
$length = strlen($data);    // 數據長度

// 打包命令類型和數據長度
$header = pack('CN', $command, $length);

// 拼接完整數據包
$packet = $header . $data;

// 輸出包的十六進製表示
echo bin2hex($packet);
?>

上面代碼中, 'C'打包命令類型(1字節無符號整數), 'N'打包數據長度(4字節大端整數)。數據體原樣拼接。

3. 用pack() 和unpack() 互轉示例

<?php
$number = 65535;
$packed = pack('n', $number);  // 按大端位元組序打包为16位無符號整數
echo 'Packed data: ' . bin2hex($packed) . PHP_EOL;

$unpacked = unpack('nvalue', $packed);  // 解包
echo 'Unpacked value: ' . $unpacked['value'] . PHP_EOL;
?>

小結

pack()是操作二進制數據的強大工具,尤其適用於網絡編程和底層數據處理。通過熟練使用格式代碼,可以準確地控制數據的字節排列和類型。