在PHP 開發中,經常需要將數據進行編碼和解碼處理,尤其是當涉及網絡傳輸或文件存儲時。 json_decode()是解析JSON 數據成PHP 數組或對象的常用函數,而pack()函數則可以將數據打包成二進製字符串,方便傳輸和存儲。本文將詳細講解如何將json_decode()得到的數組結果用pack()打包為二進制數據。
json_decode(string $json, bool $assoc = true)
解析JSON 字符串,第二個參數為true返回關聯數組,為false返回對象。
pack(string $format, mixed $args...)
根據格式字符,將參數打包成二進製字符串。格式字符決定了每個參數的類型及長度。
假設有如下JSON 數據:
{
"id": 123,
"temperature": 36.5,
"status": 1
}
我們使用json_decode()轉換為數組後,希望用pack()將其打包成二進制數據,方便網絡傳輸。
<?php
// JSON 數據
$json = '{"id":123,"temperature":36.5,"status":1}';
// 使用 json_decode 解析為關聯數組
$data = json_decode($json, true);
// 確認解析結果
// var_dump($data);
// 假设數據格式如下:
// id: 32位無符號整數 (N)
// temperature: 浮點數,32位單精度 (f)
// status: 8位無符號整數 (C)
// 注意:pack 不支持 64位浮點數格式,只能使用單精度或雙精度(d)
// 這裡選擇單精度(f)
$binary = pack(
'NfC', // 格式字符:N - 32位大端無符號整數, f - 浮點數, C - 8位無符號整數
$data['id'],
$data['temperature'],
$data['status']
);
// 输出二进制數據的十六进制表示,方便查看
echo bin2hex($binary);
?>
N表示32位無符號大端整數(網絡字節序),適合傳輸和跨平台。
f表示32位單精度浮點數。
C表示8位無符號整數。
這裡將id打包為網絡字節序的整數, temperature為浮點數, status為字節。
為了驗證打包的正確性,可以用unpack()函數解包:
<?php
// 之前打包后的二进制數據
$binary = pack('NfC', 123, 36.5, 1);
// 解包,格式字符必須與打包時對應
$unpacked = unpack('Nid/ftemperature/Cstatus', $binary);
print_r($unpacked);
?>
輸出:
Array
(
[id] => 123
[temperature] => 36.5
[status] => 1
)
如果JSON 中包含多維數組或者字符串,需要先設計好二進制格式。常見做法是:
定長字段用固定格式打包;
字符串用長度+內容方式打包,例如pack('N', strlen($str)) . $str ;
數組循環打包。
示例:
<?php
$json = '{"users":[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]}';
$data = json_decode($json, true);
$binary = '';
foreach ($data['users'] as $user) {
$id = $user['id'];
$name = $user['name'];
$nameLen = strlen($name);
$binary .= pack('N', $id); // id 4位元組
$binary .= pack('N', $nameLen); // 名字長度 4位元組
$binary .= $name; // 名字字符串
}
echo bin2hex($binary);
?>
json_decode()解析JSON 字符串為PHP 數組;
pack()根據自定義格式將數據打包為二進制;
需設計好格式,考慮字段長度和類型,特別是字符串需要自帶長度信息;
結合unpack()驗證數據正確性。
更多關於pack函數的詳細格式說明,可以參考PHP 官方文檔。