という話

技術ブログにしたい

PHPでXMLをパースして中身全てを連想配列にする

PHPXMLをパースして使おうと思うとsimplexml_load_stringとかがあるんですが、これだとSimpleXMLElementクラスのオブジェクトが返ってくるので非常に使いにくいです。

SimpleXMLElementオブジェクトは配列にキャスト出来るんですが、子要素がオブジェクトのままだったりするのであまり有効ではありません

なので再帰的に変換し連想配列にしてみます

<?php
class Libs
{
  public static function parseAPI($method, $param, $type = 'GET')
  {
    $data = http_build_query($param, '', '&');

    //header
    $header = array(
      'Content-Type: application/x-www-form-urlencoded',
      'Content-Length: '.strlen($data)
    );

    $context = array(
      'http' => array(
        'method'  => $type,
        'header'  => implode("\r\n", $header),
        'content' => $data
      )
    );

    $api_url = 'http://zip.cgis.biz/xml/zip.php/'; // APIサーバ

    // APIを投げる
    $xml = file_get_contents($api_url.$method, false, stream_context_create($context));
    if (false === $xml) return false;

    // 帰ってきたXMLをパース
    $parse_xml = simplexml_load_string($xml);
    if (false === $parse_xml) return false;

    return self::xml2arr($parse_xml);
  }

  public static function xml2arr($xmlobj)
  {
    $arr = array();
    if (is_object($xmlobj))
    {
      $xmlobj = get_object_vars($xmlobj);
    }
    else
    {
      $xmlobj = $xmlobj;
    }

    foreach ($xmlobj as $key => $val)
    {
      if (is_object($xmlobj[$key]))
      {
        $arr[$key] = self::xml2arr($val);
      }
      else if (is_array($val))
      {
        foreach($val as $k => $v)
        {
          if (is_object($v) || is_array($v))
          {
            $arr[$key][$k] = self::xml2arr($v);
          }
          else
          {
            $arr[$key][$k] = $v;
          }
        }
      }
      else
      {
        $arr[$key] = $val;
      }
    }

    return $arr;
  }
}


このparseAPIメソッドAPIメソッドとパラメータ、GETかPOSTを投げると連想配列で返してくれます
今回は試しにログインが必要ない郵便番号検索APIで試してみました

$var = Libs::parseAPI('', array('zn' => '1600000'), 'GET');
var_dump($var, true);


http://zip.cgis.biz/xml/zip.php?zn=1600000
上記URLにアクセスしたXMLが以下の様に連想配列で返ってきます


  ["result"]=>
  array(9) {
    [0]=>
    array(1) {
      ["@attributes"]=>
      array(1) {
        ["name"]=>
        string(12) "ZipSearchXML"
      }
    }
    [1]=>
    array(1) {
      ["@attributes"]=>
      array(1) {
        ["version"]=>
        string(4) "1.01"
      }
    }
    [2]=>
    array(1) {
      ["@attributes"]=>
      array(1) {
        ["request_url"]=>
        string(56) "http%3A%2F%2Fzip.cgis.biz%2Fxml%2Fzip.php%3Fzn%3D1600000"
      }
    }
    [3]=>
    array(1) {
      ["@attributes"]=>
      array(1) {
        ["request_zip_num"]=>
        string(7) "1600000"
      }
    }
    [4]=>
    array(1) {
      ["@attributes"]=>
      array(1) {
        ["request_zip_version"]=>
        string(4) "none"
      }
    }
    [5]=>
    array(1) {
      ["@attributes"]=>
      array(1) {
        ["result_code"]=>
        string(1) "1"
      }
    }
    [6]=>
    array(1) {
      ["@attributes"]=>
      array(1) {
        ["result_zip_num"]=>
        string(7) "1600000"
      }
    }
    [7]=>
    array(1) {
      ["@attributes"]=>
      array(1) {
        ["result_zip_version"]=>
        string(1) "0"
      }
    }
    [8]=>
    array(1) {
      ["@attributes"]=>
      array(1) {
        ["result_values_count"]=>
        string(1) "1"
      }
    }
  }
  ["ADDRESS_value"]=>
  array(1) {
    ["value"]=>
    array(8) {
      [0]=>
      array(1) {
        ["@attributes"]=>
        array(1) {
          ["state_kana"]=>
          string(18) "トウキョウト"
        }
      }
      [1]=>
      array(1) {
        ["@attributes"]=>
        array(1) {
          ["city_kana"]=>
          string(21) "シンジュクク"
        }
      }
      [2]=>
      array(1) {
        ["@attributes"]=>
        array(1) {
          ["address_kana"]=>
          string(45) "イカニケイサイガナイバアイ"
        }
      }
      [3]=>
      array(1) {
        ["@attributes"]=>
        array(1) {
          ["company_kana"]=>
          string(4) "none"
        }
      }
      [4]=>
      array(1) {
        ["@attributes"]=>
        array(1) {
          ["state"]=>
          string(9) "東京都"
        }
      }
      [5]=>
      array(1) {
        ["@attributes"]=>
        array(1) {
          ["city"]=>
          string(9) "新宿区"
        }
      }
      [6]=>
      array(1) {
        ["@attributes"]=>
        array(1) {
          ["address"]=>
          string(4) "none"
        }
      }
      [7]=>
      array(1) {
        ["@attributes"]=>
        array(1) {
          ["company"]=>
          string(4) "none"
        }
      }
    }
  }
}


これならとっても扱いやすいですね。