pack()函數的基本語法如下:
string pack(string $format, mixed ...$values)
$format :格式字符串,定義了後面傳入值的打包方式。
$values :要打包的數據列表。
例如, pack('C', 65)會返回一個ASCII 值為65 的字節(即字符A )。
對於浮點數, pack()提供兩個關鍵的格式符號:
f :將數據作為32 位單精度浮點數進行打包。
d :將數據作為64 位雙精度浮點數進行打包。
但問題來了——字節序(endianness)在不同平台上可能不同。在pack()中可以通過前綴來指定字節序:
f / d :使用主機字節序(可能是大端也可能是小端)
g :32 位浮點數,使用小端字節序(類似於Intel 架構)
G :32 位浮點數,使用大端字節序
e :64 位浮點數,小端字節序
E :64 位浮點數,大端字節序
注意: g / G / e / E是從PHP 7.0 開始引入的。
假設我們要將浮點數3.14打包為網絡傳輸所需的二進制流(一般要求使用大端):
<?php
$float = 3.14;
$binary = pack('G', $float); // 打包為大端的32位浮點數
echo bin2hex($binary); // 輸出十六進制結果查看
?>
輸出(可能類似):
4048f5c3
這個值可以在其他支持IEEE 754 標準的語言中解析回來為3.14。
我們可以使用unpack()驗證上面打包的值是否正確:
<?php
$binary = pack('G', 3.14);
$result = unpack('Gfloat', $binary);
echo $result['float']; // 輸出 3.14
?>
假設你正在構建一個API,需要將多個浮點數打包上傳:
<?php
$data = [1.23, 4.56, 7.89];
$binary = '';
foreach ($data as $num) {
$binary .= pack('G', $num); // 大端格式
}
// 將打包後的數據上傳到服務端
$url = 'https://m66.net/upload-float-data';
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/octet-stream\r\n",
'content' => $binary,
],
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
如果對浮點數精度要求較高,請使用d (64 位雙精度)。
跨平台通信時,務必統一字節序,推薦使用G (32 位大端)或E (64 位大端)。
使用bin2hex()或unpack()來調試打包結果。
不要在未明確知道字節序的情況下使用默認的f或d 。