読者です 読者をやめる 読者になる 読者になる

jsonをphpでparseする際にコロンが含まれてた時の対応メモ

明らかに次もはまりそうなので、メモ

やりたいこと

rssをjson形式で返してくれるサイトがあったので、それをphpでparseしようと思った。

code

    $rss_file = file_get_contents($rss_url);
    $rss_data_obj = json_decode($rss_file);

json_decodeした場合、stdClassで返却される。

object(stdClass)#22 (1) {
  ["feed"]=>
  object(stdClass)#23 (8) {
    ["author"]=>
 ...


stdClassなので、以下のように値を取ればいいのだが、

$rss_data_obj->feed->author;


困ったのはこういうパターン

    ["entry"]=>
    object(stdClass)#27 (12) {
      ["im:name"]=>
      object(stdClass)#28 (1) {
...

['im:name'] という名前だと、->im:name というようにオブジェクトとして呼び出せない。

しょうがないのでarrayにキャストする

参考: Object→Arrayにキャストする ~多次元配列編~ | Suinasia

     private function obj2arr($obj) {
         if ( !is_object($obj) ) return $obj;
         $arr = (array) $obj;
         foreach ( $arr as &$a ) {
             $a = $this->obj2arr($a);
         }
         return $arr;
     }


ここでだいたいarrayにキャストできるんだが、元々配列が含まれると、配列以下を見てくれない事に気づいた。

    ["icon"]=>
    array(1) {
      ["label"]=>
      string(35) "http://itunes.apple.com/favicon.ico"
    }
    ["link"]=>
    array(2) {
      [0]=>
      object(stdClass)#59 (1) {
        ["attributes"]=>
...

"icon" はうまくarrayにキャストできているけど、"link"は元々arrayなので、[0]個目の要素以下がキャストされてない。


しょうがないので以下のようにした。

private function obj2arr($obj) {
    if ( !is_object($obj) && $this->is_hash($obj) ) return $obj;
    $arr = (array) $obj;
    foreach ( $arr as &$a ) { 
        $a = $this->obj2arr($a);
    }   
    return $arr;
}
private function is_hash($array) {
    if (!is_array($array)) {
        return true;
    }   
    list($k) = each($array);
    return $k !== 0;
}