人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

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="あ";
このような文字列データから生成する方法はあるのでしょうか。

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

●質問者: n_maco2
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● JULY
●200ポイント ベストアンサー
<?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
)

と表示されました。


JULYさんのコメント
ただ、fread しているところを file_get_contents にしても、この場合は結果に変わりは無かったです。 一応、バイナリセーフな読み出しは fread、という事にはなっています。 http://php.net/manual/ja/function.fread.php じゃぁ、どんな時に、file_get_contents だとダメになるのか、自分も改めて疑問になってきました(^^;。 最初に pack する時に 0x00 を間に入れたら、その後ろが切れてしまうとか、期待したんだけど、普通に読み出せました。う?ん。

うぃんどさんのコメント
http://php.net/manual/ja/function.file-get-contents.php >> この関数はバイナリデータに対応しています。 << 以上、ご参考まで

n_maco2さんのコメント
ご回答ありがとうございます。 いただいた内容でもう少しはっきりとバイナリについて理解できてきました。結局unpackを使って分解するのですね、そこらへんわかってなかったです。ありがとうございます。 file_get_contents は追加でコメントいただいた通り、「バイなりセーフ」とは書いていないですが「対応しています」とは書いてあるんですよね。何か意味に違いがあるのか無いのかよくわからないのですが・・挙動としては同じに思えますね

うぃんどさんのコメント
>意味に違いがあるのか無いのか 違いはありません。日本語に翻訳する際に発生した表記の揺れです。 それぞれ英文のほうを見てみると、判りやすいかもしれません。 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さんの回答内コメントで邪魔させていただいた次第です。

n_maco2さんのコメント
echo側が文字列として解釈して処理を行っているということですね。とするとバイナリデータ用の関数(画像系とか?)を使った場合には、バイナリとして解釈して処理を行うのでしょうか。そういえば、同様に変数に入れて画像ファイルを作っていた覚えがあります。詳しいご説明ありがとうございます。 windofjulyさんご回答いただきましてありがとうございます。気付いておりませんでした。(名前表示してくれないのは分かりづらいですねぇ・・) 諸々ご配慮ありがとうございました!
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ