Serializerを使ってPHPでのJSONと配列やオブジェクトの相互変換を楽にする

Serializerとは

PHPの配列やオブジェクトをXMLJSONシリアライズしたり、その逆にデシリアライズすることができるライブラリです。

PHP向けのre:dash APIクライアントを作っている時に見つけました。

github.com

SymfonyにもSerializerというコンポーネントがありますが、Githubのスター数が多いという理由で今回はschmittjoh/serializerを選択しました。

Githubのスター数こそ少ないですが、Symfony内部で使われていそうなので、実ユーザーはこちらのほうが多いかもしれません。

インストール

Composerでインストールできます。

$ composer require jms/serializer

使い方

簡単なサンプルコードで使い方を紹介します。

サンプルコード

シリアライズ

まずはPHPの配列をJSONシリアライズしてみます。

<?php

$loader = require_once './vendor/autoload.php';

$data = [
    ['name' => 'PHP', 'description' => 'PHP is a popular general-purpose scripting language that is especially suited to web development.'],
    ['name' => 'Ruby', 'description' => 'A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.'],
    ['name' => 'Go', 'description' => 'Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.'],
];

$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$jsonContent = $serializer->serialize($data, 'json');
echo $jsonContent;

これを実行するとこんな感じになります。

$ php example.php
[{"name":"PHP","description":"PHP is a popular general-purpose scripting language that is especially suited to web development."},{"name":"Ruby","description":"A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write."},{"name":"Go","description":"Go is an open source programming language that makes it easy to build simple, reliable, and efficient software."}]

JSONがPretty printされていないので読みにくいですが、配列がJSONに変換されていることがわかります。でも、これはjson_encode関数とあまり変わらないですね。

シリアライズ

シリアライズのサンプルコードを少し改変して、JSONからのデシリアライズも試してみます。

<?php

$loader = require_once './vendor/autoload.php';

use Doctrine\Common\Annotations\AnnotationRegistry;
use JMS\Serializer\Annotation\Type;

AnnotationRegistry::registerLoader('class_exists');

class Language
{
    /**
     * @Type("string")
     */
    public $name;

    /**
     * @Type("string")
     */
    public $description;
}

$data = [
    ['name' => 'PHP', 'description' => 'PHP is a popular general-purpose scripting language that is especially suited to web development.'],
    ['name' => 'Ruby', 'description' => 'A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.'],
    ['name' => 'Go', 'description' => 'Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.'],
];

$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$jsonContent = $serializer->serialize($data, 'json');
// echo $jsonContent;

$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$object = $serializer->deserialize($jsonContent, 'array<Language>', 'json');

var_dump($object);

JSONからオブジェクトにデシリアライズする場合は、使用するクラスのメンバー変数にアノテーションを付ける必要があります。

ここでは、Languageクラスを用意し、JSONLanguageオブジェクトの配列にデシリアライズしています。

実行してみると、以下のような感じです。

$ php example.php
array(3) {
  [0]=>
  object(Language)#23 (2) {
    ["name"]=>
    string(3) "PHP"
    ["description"]=>
    string(97) "PHP is a popular general-purpose scripting language that is especially suited to web development."
  }
  [1]=>
  object(Language)#6 (2) {
    ["name"]=>
    string(4) "Ruby"
    ["description"]=>
    string(156) "A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write."
  }
  [2]=>
  object(Language)#27 (2) {
    ["name"]=>
    string(2) "Go"
    ["description"]=>
    string(111) "Go is an open source programming language that makes it easy to build simple, reliable, and efficient software."
  }
}

まとめ

REST APIを使う場面では、ほとんどの場合JSONを使うことになりますが、決まった形式のJSONであればSerializerを使うことでPHPでの扱いが楽になるかもしれません。