前回まででPHPおよびJavaScriptでMessagePackを使う準備をしました。
今回は実際にコードを書いてMessagePackへのエンコードやデコード、そしてPHPとJavaScriptでの送受信をしてみます。
PHPでMessagePackを使う
PHPでMessagePackを使う場合、ライブラリのインストールさえできてしまえばとても簡単です。
まず以下がArrayをMessagePackにエンコードするコードです。
<?php
require_once('./vendor/autoload.php');
use MessagePack\Packer;
$packer = new Packer();
$array = array('あいうえお', 'カキクケコ');
$msgpack_data = $packer->pack($array);
$msgpack_dataをvar_dump()でブラウザに出力してみると、少し文字化けした状態で表示されます。
同様にjson_encode()して出力した場合、MessagePackと比較するとかなり長いですね。
確認方法としてはちょっと強引ですし実際の速さの測定などはしていないので正確なことは言えませんが、通信時のデータ量は少なくなりそうですね。
そしてデコードも簡単で、エンコードとほとんど同じようなコードでOKです。
<?php
require_once('./vendor/autoload.php');
use MessagePack\Unpacker;
$unpacker = new Unpacker();
$array = $unpacker->unpack($msgpack_data);
これで元のArrayに戻ります。
JavaScriptでMessagePackを使う
JavaScriptでMessagePackを使う場合もやはり同様でとても簡単です。
<script type="text/javascript" src="./msgpack.min.js"></script>
<script type="text/javascript">
var msgpack_data = msgpack.encode(["あいうえお", "カキクケコ"]);
</script>
msgpack_dataをconsole.logするとUint8Arrayで出力されます。
デコードは以下です。
<script type="text/javascript" src="./msgpack.min.js"></script>
<script type="text/javascript">
var array = msgpack.decode(msgpack_data);
</script>
PHPよりも更に簡単です。
PHPから出力されるMessagePackをJavaScriptで受け取る
実はPHPとJavaScriptでのデータ送受信については結構悩みました。
というのはPHPでエンコードされたものをecho()で単純に出力し、それをJavaScript&jQueryでAjax読み込みしようとするとうまくいきませんでした。
コードは以下のようなものです。まずPHP。
<?php
require_once('./vendor/autoload.php');
use MessagePack\Packer;
$packer = new Packer();
$array = array('あいうえお', 'カキクケコ');
$msgpack_data = $packer->pack($array);
echo $msgpack_data;
上記をapi.phpとして保存しておき、JavaScript側のコードを以下のように書きます。
<script type="text/javascript" src="./msgpack.min.js"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript">
$.get('./api.php', function(msgpack_data){
var array = msgpack.decode(msgpack_data);
console.log(array);
});
</script>
するとエラーが発生します。JSONでデータを出力するAPIを作る場合はこれでOKなはずと思いながらやってみましたがダメでした。
これを解決するためにいろいろ調べたところ、今回の場合はPHP側でMessagePackエンコードされたデータを更にBase64でエンコードし、JavaScriptでBase64デコード&MessagePackデコードをすればOKということが判りました。
まずPHP。
<?php
require_once('./vendor/autoload.php');
use MessagePack\Packer;
$packer = new Packer();
$array = array('あいうえお', 'カキクケコ');
$msgpack_data = $packer->pack($array);
echo base64_encode($msgpack_data);
そしてJavaScript。
<script type="text/javascript" src="./msgpack.min.js"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript">
var Base64toUint8Array = function (str) {
return atob(str).split('').map(function (c) { return c.charCodeAt(0); });
}
$.get('./api.php', function(msgpack_data){
var array = msgpack.decode(Base64toUint8Array(msgpack_data));
console.log(array);
});
</script>
これでOKでした。本当にBase64エンコード&デコードが必要かは判りませんが・・・とりあえずは解決できました。
全体的な速度等はやはり不明です
というわけでPHPとJavaScriptでデータ送受信をしてみました。
例えばMessagePackを使ったWebサービスを作った場合、送受信するデータが短くなるのは間違いないので、ネットワークを介した通信部分の速度は上がると思われます。
が、今回のPHPとJavaScriptでは(本当に必要かどうか不明な)Base64のエンコード&デコードを含んでますし、全体としてパフォーマンスが良くなるのかどうかも不明かなと思っています。
その辺の測定なんかはまたいずれということで。。。