<< 届かない mailto 〜DoCoMo 改行コードの罠〜 | main | PHP の include で半角カナが文字化け >>

PHP での NULLバイトのバイナリデータ生成 〜困ったときの pack関数〜

Flash の特定のアイコンの表示/非表示を管理画面で操作したい, という要望に答えるべく
SWFファイルに変数を埋め込むライブラリを使用させてもらいました。

中身は結構単純で, 変数の key/value の組を SWFファイルのフォーマットに従って特定の領域に格納しているもの。
このライブラリを使って変数を埋め込んでみたのですが, うまく動作しません。

出力されたファイルをバイナリエディタで見てみると, 期待通りの値が出力されていない模様。

$dat = "\x96" . $var1 . "\x00" . $key ."\x00";

のようにバイナリデータを生成してそれをファイルに吐き出しているのですが, どうも "\x00" の扱いがおかしい。

$bin = "\x00\x11\x22\x00\x33\x44\x00\x55";

$fp = fopen('pack.dat', 'w');
fwrite($fp, $bin);
fclose($fp);

実行してみると, ファイルには何も吐き出されません。

$bin = "\x11\x00\x22\x00\x33\x44\x00\x55";

に変更してみると, 0x11 だけのバイナリデータが生成されました。

どうやら NULLバイト("\x00") で文字列の終わりとみなされて, それ以降に何があっても無視されるみたい。
昔のバージョンの PHP では動作していたけど, (セキュリティがらみの修正で?)どこかのバージョンで挙動が変わったんでしょう。
# $HTTP_GET_VARS とか使ってるし。

さて, 困った。
バイナリ操作で困った時は pack関数調べれば何とかなるか...
で, NULLバイトをパックするコードを発見。

pack('x')

で 00 を埋め込むことができます。

ということで, 上記の意図した通りのバイナリファイルを生成するには,

$bin = pack('x') . "\x11\x22" . pack('x') . "\x33\x44" . pack('x') . "\x55";
$bin = pack('xc2', 0x11, 0x22) . pack('xc2', 0x33, 0x44) . pack('xc', 0x55);
$bin = pack('xc2xc2xc', 0x11, 0x22, 0x33, 0x44, 0x55);

のいずれかで OK。

Webプログラミングはテキスト処理が殆どで, バイナリデータを扱う機会があまりないので馴染みが薄いかも知れませんが, 困ったときは pack関数のマニュアルみれば何とかなります。

...多分(;・∀・)
はてブへ追加 この記事のはてブユーザ
PHP | comments (0) | - | pagetop↑

Comments

Post your Comment