Pack()関数の基本的な構文は次のとおりです。
string pack(string $format, mixed ...$values)
$フォーマット:フォーマット文字列。後で渡された値のパッケージング方法を定義します。
$値:パッケージ化されるデータのリスト。
たとえば、 Pack( 'C'、65)は、 ASCII値が65(つまり、文字A )のバイトを返します。
フローティングポイント番号の場合、 pack()は2つのキー形式シンボルを提供します。
F :データを32ビットのシングルエシジョンフローティングポイント番号としてパッケージ化します。
D :データを64ビットのダブルサイジョンフローティングポイント番号としてパッケージ化します。
しかし、問題は、エンデアネスが異なるプラットフォームで異なる場合があります。 pack()では、プレフィックスでバイトの順序を指定できます。
f / d :ホストのエンディアンネスを使用します(多分ビッグエンディアンまたは小さなエンディアン)
G :リトルエンディアンエンディアンを使用して、32ビットの浮動小数点数(Intel Architectureに似ています)
G :ビッグエンディアンバイト順序を使用した32ビットの浮動小数点数
E :64ビットフローティングポイント番号、リトルエンディアンバイトオーダー
E :64ビットフローティングポイント番号、ビッグエンディアンバイトオーダー
注: G / G / E / Eは、PHP 7.0から導入されました。
フローティングポイント番号3.14をネットワーク伝送に必要なバイナリストリームとしてパッケージ化するとします(Big Endianを使用):
<?php
$float = 3.14;
$binary = pack('G', $float); // ビッグエンドとして詰め込まれています32ビットフローティングポイント番号
echo bin2hex($binary); // 出力16進結果ビュー
?>
出力(おそらく類似):
4048f5c3
この値は、IEEE 754標準をサポートする他の言語では3.14に戻すことができます。
uppack()を使用して、上記の値が正しいことを確認できます。
<?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);