ヤフー株式会社は、2023年10月1日にLINEヤフー株式会社になりました。LINEヤフー株式会社の新しいブログはこちらです。LINEヤフー Tech Blog

テクノロジー

PHP SERIALIZEのススメ

オークション事業部 開発部のやまけんです。

遅ればせながら、新年明けましておめでとうございます。

さて、オークションTechBlogも第4回目となりました。

今回はWebAPIとしての一つの形態であるPHP Serializeに関してお話します。

WebAPIは、一般的にはRESTと呼ばれるXMLを主体としたレスポンスを返却し、呼び側がXMLを解析するというものが主流となっています。
(RESTには、RESTfulと呼ばれる概念がありますが、それはまた別の機会にお話したいと思います)

さて、PHP Serializeですが、これはPHP言語で表現されるデータやクラスをサーバー側で文字列化して、呼び側でデータやクラスに復元するという手法です。

APIを利用する呼び側がPHPで実装されている場合には、REST形式のAPIよりも格段に利便性が高いです。なんせ解析処理が必要なく、そのまま関数を呼ぶイメージでデータが返却されるのですから。

オークションAPIでは、内部的にはXMLをベースとしており、今後逐次リリース予定であるPHP Serializeは、ベースであるXMLからPHP Serialize形式に変換しています。

つまり、
[XML] -> [PHP Serialize]
という変換が発生します。

PHP言語ではSimpleXMLというXML解析クラスが存在します。configureで "--enable-simplexml" を指定することで利用が可能です。

XMLからPHP Serialize形式に変換するには、上述したSimpleXMLを利用して
[XML] -> [SimpleXML] -> [PHP Serialize]
とするのが一番簡単です。

しかし、ここで1つ問題が発生します。

SimpleXMLクラスは、PHPのExtentionという位置づけのため、呼び側であるClientに必ず入っているとは言い切れないということです。

つまり、SimpleXMLをserialize(文字列化)しても、呼び側のPHP環境にSimpleXMLが存在しない場合には、復元ができないということです。

当然ながら、使い手の環境に制限を与えるのは極力ない方が良いので、さらに変換処理を一段挟み
[XML] -> [SimpleXML] -> [PHP array形式] -> [PHP Serialize]
とするのが、最も使い手(呼び側)にとって便利なPHP Serialize形式のAPIとなるでしょう。

SimpleXMLからPHPのarray形式に変換するサンプルコードをご紹介します。

<?php
function simpleXml2array($simpleXml, &$hash, $isRecursive = false) {
    if (!$isRecursive) {
        //
        // rootタグを設定。
        //
        $hash[$simpleXml->getName()] = null;

        //
        // 最上位タグの属性(attribute)を設定
        //
        foreach($simpleXml->attributes() as $key => $value) {
            $hash[$simpleXml->getName()][$key] = (string)$value;
        }
    }

    foreach($simpleXml->children() as $key => $value) {
        $values = (array)$value;

        if (0 < count($values)) {
            if (array_key_exists(0, $values)) {

                $setValue = null ;
                if (0 == strcasecmp((string)$value, "true")) {
                    $setValue = true;
                } elseif (0 == strcasecmp((string)$value, "false")) {
                    $setValue = false;
                } else {
                    $setValue = (string)$value;
                }

                if (array_key_exists($key, $hash)) {
                    if (! array_key_exists(0, $hash[$key])) {
                        $tmpHash = $hash[$key];
                        unset($hash[$key]);
                        $hash[$key][0] = $tmpHash;
                    }
                    array_push($hash[$key], $setValue);
                } else {
                    $hash[$key] = $setValue;
                }
            } else {
                //
                // 子要素あり。再帰。
                //
                $childHash = array();
                simpleXml2array($value, $childHash, true);
                if (array_key_exists($key, $hash)) {
                    if (! array_key_exists(0, $hash[$key])) {
                        $tmpHash = $hash[$key];
                        unset($hash[$key]);
                        $hash[$key][0] = $tmpHash;
                    }
                    array_push($hash[$key], $childHash);
                } else {
                    $hash[$key] = $childHash;
                }
            }
        } else {
            //
            // value=null
            //
            $hash[$key] = '';
        }
        //
        // set attributes.
        //
        foreach($simpleXml->$key->attributes() as $attr_key => $attr_value) {
            $hash[$key][$attr_key] = (string)$attr_value;
        }
    }
}

注:
上記のサンプルでは、型に関してはstring/booleanのみを意識しており、数値型の考慮はされてません。

PHP言語もウェブ開発言語として、広く一般的な言語となってきましたので、WebAPIの一つの表現手法としてPHP Serializeがもっともっと広まればいいなと思っています。

WebAPIは、日進月歩で扱いが簡単になっていっています。 APIを通して、より皆様との接点を増やしていければ幸いです!

こちらの記事のご感想を聞かせください。

  • 学びがある
  • わかりやすい
  • 新しい視点

ご感想ありがとうございました

このページの先頭へ