The basic syntax of the pack() function is as follows:
string pack(string $format, mixed ...$values)
$format : format string, which defines the packaging method of the value passed in later.
$values : A list of data to be packaged.
For example, pack('C', 65) returns a byte with an ASCII value of 65 (i.e., character A ).
For floating point numbers, pack() provides two key format symbols:
f : Package the data as a 32-bit single-precision floating point number .
d : Package the data as a 64-bit double-precision floating point number .
But the problem is - endianness may be different on different platforms. In pack() you can specify byte order by prefix:
f / d : Use host endianness (maybe big endian or small endian)
g : 32-bit floating point number, using little endian endian endian (similar to Intel architecture)
G : 32-bit floating point number, using big endian byte order
e : 64-bit floating point number, little-endian byte order
E : 64-bit floating point number, big-endian byte order
Note: g / G / e / E was introduced starting with PHP 7.0.
Suppose we want to package floating point number 3.14 as binary streams required for network transmission (using big endian):
<?php
$float = 3.14;
$binary = pack('G', $float); // Packed as big-end32Bit floating point number
echo bin2hex($binary); // Output hexadecimal result view
?>
Output (probably similar):
4048f5c3
This value can be parsed back to 3.14 in other languages that support the IEEE 754 standard.
We can use unpack() to verify that the value packaged above is correct:
<?php
$binary = pack('G', 3.14);
$result = unpack('Gfloat', $binary);
echo $result['float']; // Output 3.14
?>
Suppose you are building an API and need to package and upload multiple floating point numbers:
<?php
$data = [1.23, 4.56, 7.89];
$binary = '';
foreach ($data as $num) {
$binary .= pack('G', $num); // Big endian format
}
// Upload the packaged data to the server
$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);
If you have high requirements for floating point accuracy, use d (64-bit double).
When communicating across platforms, it is necessary to unify the endianness, and it is recommended to use G (32-bit big-endian) or E (64-bit big-endian).
Use bin2hex() or unpack() to debug the packaged results.
Do not use the default f or d without explicitly knowing the endianness.