DF

複数の Codec を連結させる

Author : trashtoy

Table of Contents

CodecChain の概要

例えばとある値を JSON に変換した後それを Base64 エンコードするといった具合に, 複数のエンコード処理を連続して施す場合に役立つのが CodecChain というクラスです. CodecChain を利用することで, 複数の Codec を連結させて 1 つの Codec として扱うことができます.

CodecChain の適用例

冒頭にあげたような JSON 化と Base64 エンコードを組み合わせた CodecChain を例として作成します. この Codec は以下のような挙動を行います.

  • encode: 任意の値を JSON エンコードし, その結果を Base64 でエンコードした結果を返す
  • decode: 与えられた Base64 文字列をデコードし, その結果を JSON としてデコードする

これを実現するコードは以下の通りです.

CodecChain クラスのコンストラクタには「エンコードする順番」通りに Codec オブジェクトを指定します. 今回の場合は 第 1 引数に JsonCodec, 第 2 引数に Base64Codec オブジェクトとなります.

  1. // $jsonCodec: 任意の値と JSON の相互変換を行う
  2. $encodeOptions array(
  3.     Peach_DF_JsonCodec::PRETTY_PRINT => true,
  4.     Peach_DF_JsonCodec::PRESERVE_ZERO_FRACTION => true,
  5.     Peach_DF_JsonCodec::UNESCAPED_UNICODE => true,
  6. );
  7. $decodeOptions array(
  8.     Peach_DF_JsonCodec::OBJECT_AS_ARRAY => true,
  9.     Peach_DF_JsonCodec::BIGINT_AS_STRING => true,
  10. );
  11. $jsonCodec new Peach_DF_JsonCodec($encodeOptions$decodeOptions);
  12.  
  13. // $base64Codec: Json と Base64 の相互変換を行う
  14. $base64Codec Peach_DF_Base64Codec::getInstance();
  15.  
  16. // 任意の値を, JSON を経由して Base64 に変換する (またはその逆を行う) Codec
  17. $chain new Peach_DF_CodecChain($jsonCodec$base64Codec);
  18.  
  19. $data array(
  20.     "foo" => 2.0,
  21.     "bar" => 3.14,
  22.     "baz" => "テスト",
  23. );
  24.  
  25. // 配列を, JSON を経由して Base64 に変換
  26. $encoded $chain->encode($data);
  27. echo "encode:"PHP_EOL;
  28. var_dump($encoded);
  29.  
  30. // Base64 文字列を, JSON を経由して配列に変換
  31. echo "decode:"PHP_EOL;
  32. $decoded $chain->decode($encoded);
  33. var_dump($decoded);

このコードは以下の結果を出力します.

        encode:
        string(84) "ew0KICAgICJmb28iOiAyLjAsDQogICAgImJhciI6IDMuMTQsDQogICAgImJheiI6ICLjg4bjgrnjg4giDQp9"
        decode:
        array(3) {
          'foo' =>
          double(2)
          'bar' =>
          double(3.14)
          'baz' =>
          string(9) "テスト"
        }
                    

さらに別の Codec を追加で連結させる

サンプルコードでは 2 種類の Codec を連結させた例を記載しましたが, さらに別の Codec を前後に連結させることもできます. そのためのメソッドが append() および prepend() です.

以下に append() および prepend() を使用したサンプルコードを挙げます.

  1. $chain1 new CodecChain($c1$c2);
  2. $chain2 $chain1->prepend($c0);     // $c0, $c1, $c2 の順に連結された CodecChain
  3. $chain3 $chain1->append($c3);      // $c1, $c2, $c3 の順に連結された CodecChain

$chain2, $chain3 に対して同様の操作でさらに別の Codec を追加することも可能です.