PHPによるpack関数について質問です


たとえば下記のようなコードで”あ”という文字列を保存した場合に
-
$a = pack('C*', 0xE3, 0x81, 0x82); // =あ
file_put_contents('./hoge.bin', $a);
-

できたファイルをバイナリエディタで表示すると下記のように表示されます
-
0000000: e3 81 82 ...
-

これを逆に下記のコードで$aに読み込んだ場合
-
$a = file_get_contents('./hoge.bin');
-

$aには文字列としての"あ"が読み込まれるとおもいますが、これをバイナリデータである"0xE30, x810, x82"として読み込む方法はあるのでしょうか。file_get_contentsをすると必ず文字列として読み込まれてしまうのかな、と考えておりますがあっておりますでしょうか。

また、同じような質問になりますが、下記のようなunpackのコードで
$hoge = unpack('C*hoge', $a);
引数の$aに渡すべきバイナリデータを
$a="あ";
このような文字列データから生成する方法はあるのでしょうか。

お手数ですがお分かりになるかたいらっしゃいましたらお教えいただければと思います。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2012/07/30 21:29:21
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:JULY No.1

回答回数966ベストアンサー獲得回数247

ポイント200pt
<?php
    $a = pack('C*', 0xE3, 0x81, 0x82); // =あ
    file_put_contents('./hoge.bin', $a);

    $handle = fopen('./hoge.bin', 'rb');
    $data = unpack('C*', fread($handle, filesize('./hoge.bin')));
    fclose($handle);
    print_r($data);
?>

かな?
これで、

Array
(
    [1] => 227
    [2] => 129
    [3] => 130
)

と表示されました。

他3件のコメントを見る
id:windofjuly

>意味に違いがあるのか無いのか

違いはありません。日本語に翻訳する際に発生した表記の揺れです。
それぞれ英文のほうを見てみると、判りやすいかもしれません。

http://php.net/manual/en/function.fread.php

Binary-safe file read


http://php.net/manual/en/function.file-get-contents.php

This function is binary-safe.


fread は2000年5月リリースのphp4.0.0から装備され、
file-get-contentsは2002年12月リリースのphp4.3.0で装備。
徐々に関数が増えて、楽できるようになってはきましたが、
関数が増えすぎて、どっちを使えば良いか迷うのは逆に面倒ですね。
この場合は、どちらもかなり以前からあるもので安定感もありますので、
単純に楽なほうを選択しておけば良いでしょう。


さて、本題のほうですが、
$a = file_get_contents('./hoge.bin'); を実行した場合、
$aの中身は0xE3, 0x81, 0x82になっています。
echo $aなどを実行すると、文字コードが入っているものとして取り扱われて、
画面には「あ」と出力されているのです。
(「あ」として出力するために、文字コードの設定が存在します。
 文字コードの設定を間違うと当然ながら文字化けしてしまいます。)

$aの中身を文字コードの設定に合わせて「あ」と出力させるのではなく、
自分の思うとおりに取り出して使いたい場合は、
「指定した方法で包装を解く(unpack)」という手間をかけるわけです。

ちなみに、2つ目のコメントと、このコメントはJULYさんではなく、
packの言葉の質問で回答をしたwindofjulyです。
見えにくいですがアイコンが違うのでわかるかと思います。
(コメント欄横に表示されているアイコンにマウスを置くとIDが表示されます)

JULYさんの回答の解説みたいな内容なので、新規回答にはせず、また、
もう一つの質問( http://q.hatena.ne.jp/1343381672 )へも繋がる話題なので、
JULYさんの回答内コメントで邪魔させていただいた次第です。

2012/07/28 10:55:37
id:n_maco2

echo側が文字列として解釈して処理を行っているということですね。とするとバイナリデータ用の関数(画像系とか?)を使った場合には、バイナリとして解釈して処理を行うのでしょうか。そういえば、同様に変数に入れて画像ファイルを作っていた覚えがあります。詳しいご説明ありがとうございます。

windofjulyさんご回答いただきましてありがとうございます。気付いておりませんでした。(名前表示してくれないのは分かりづらいですねぇ・・)
諸々ご配慮ありがとうございました!

2012/07/28 13:58:04

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません