pack

(PHP 4, PHP 5, PHP 7, PHP 8)

packデータをバイナリ文字列にパックする

説明

pack(string$format, mixed...$values): string

指定された引数を format に基づいて バイナリ文字列にパックします。

この関数のアイデアは Perl からのものであり、フォーマット指定用の コードは Perl と同様に動作します。しかし、中には存在しない書式コードもあります。 たとえば Perl の "u" は存在しません。

符号付及び符号無しの区別は関数 unpack() にのみ 影響を与えます。関数 pack() は符号付及び符号無しの フォーマットコードのどちらでも同じ結果となることに注意しましょう。

パラメータ

format

フォーマット文字列は、 フォーマットコードの後にオプションの反復指定用引数が続く形式と なっています。反復指定用引数として整数値、または入力データの最後まで 反復を意味する * のどちらかを指定することができます。 a, A, h, H の場合、 反復数はそのデータ引数が取得する文字の数を指定します。反復数が @ の場合、 次のデータを置く場所の絶対位置を表します。その他の場合、反復数は データ引数が使われる数を指定し、結果のバイナリ文字列にパックされます。

現在、実装されているものを以下に示します。

pack() の書式文字
コード説明
aNUL で埋めた文字列
A空白で埋めた文字列
h十六進文字列、下位ニブルが先
H十六進文字列、上位ニブルが先
csigned char
Cunsigned char
ssigned short (常に 16 ビット、マシンのバイトオーダー)
Sunsigned short (常に 16 ビット、マシンのバイトオーダー)
nunsigned short (常に 16 ビット、ビッグエンディアンバイトオーダー)
vunsigned short (常に 16 ビット、リトルエンディアンバイトオーダー)
isigned integer (サイズおよびバイトオーダーはマシン依存)
Iunsigned integer (サイズおよびバイトオーダーはマシン依存)
lsigned long (常に 32 ビット、マシンのバイトオーダー)
Lunsigned long (常に 32 ビット、マシンのバイトオーダー)
Nunsigned long (常に 32 ビット、ビッグエンディアンバイトオーダー)
Vunsigned long (常に 32 ビット、リトルエンディアンバイトオーダー)
qsigned long long (常に 64 ビット、マシンのバイトオーダー)
Qunsigned long long (常に 64 ビット、マシンのバイトオーダー)
Junsigned long long (常に 64 ビット、ビッグエンディアンバイトオーダー)
Punsigned long long (常に 64 ビット、リトルエンディアンバイトオーダー)
ffloat (サイズおよび表現はマシン依存)
gfloat (サイズはマシン依存。 リトルエンディアンバイトオーダー)
Gfloat (サイズはマシン依存。 ビッグエンディアンバイトオーダー)
ddouble (サイズおよび表現はマシン依存)
edouble (サイズはマシン依存。 リトルエンディアンバイトオーダー)
Edouble (サイズはマシン依存。 ビッグエンディアンバイトオーダー)
xNUL バイト
X1 バイト戻る
ZNUL 埋め文字列
@絶対位置まで NUL で埋める
values

戻り値

バイナリ文字列を含むデータを返します。

変更履歴

バージョン説明
8.0.0 この関数は、失敗時に false を返さなくなりました。
7.2.0floatdouble 型は、ビッグエンディアンとリトルエンディアンを両方サポートしました。
7.0.15,7.1.1 "e", "E", "g" および "G" コードが、float と double のバイトオーダーをサポートするために追加されました。

例1 pack() の例

<?php
$binarydata
= pack("nvc*", 0x1234, 0x5678, 65, 66);
?>

この結果のバイナリ文字列の長さは 6 バイト長で、バイト列 0x12, 0x34, 0x78, 0x56, 0x41, 0x42となります。

注意

警告

PHP は、int 型の値を内部的に格納する際に サイズがマシン依存の符号付き値 (C の long 型) を使うことに注意しましょう。int 型の範囲外の数値となる整数リテラルや演算結果は float として保持されます。この float 値を integer としてパックする際には まず最初に integer 型へのキャストを行います。 その結果、できあがるバイトパターンは期待通りにはならないかもしれません。

この問題にもっとも関連するのが、符号なしの数値で int 型で表現できるものをパックする場合です。 int 型のサイズが 32 ビットであるシステムでのキャスト結果は、 (実装で定義されている標準 C の符号なし型から符号付き型への変換に依存しますが) まるで int が符号なし整数であるかのような同一のバイトパターンになることがよくあります。 int 型のサイズが 64 ビットであるシステムでは、 たいていの場合は float の仮数部のサイズが足りず、 値の精度を損なわずに保持することができません。 ネイティブの 64 ビット C int 型を持つシステム (UNIX 系システムのほとんどは持っていません) では、上側の範囲の値で パック書式 I を使うための唯一の方法は、 希望する符号なし値と同じバイト表現になるような負の int 値を作ることになります。

参考

  • unpack() - バイナリ文字列からデータを切り出す
To Top