phpでcannot use string offset as an arrayエラー


Yahooの商品検索Apiの php serialized を使っていたら 「cannot use string offset as an array」
とかいう見たこともないエラーが出たので対応メモ。

エラーが出るコードはこんなかんじ

//めんどくさいので取得の部分はぶきますが
//Yahoo APIで phpのserializedデータを取得
$unserializedData = unserialize(file_get_contents('http://shopping.yahooapis.jp/ShoppingWebService/V1/php/itemSearch?'));

foreach ($unserializedData['ResultSet'][0]['Result'] as $k=>$v) {
    print($v['Image']['Medium']); //これがPHP5だとエラーになる4だとOK
}

肝心のYahooの商品検索Apiのリターンはこんなかんじ(適当にはしょってます)

[ResultSet] => Array
        (
            [totalResultsAvailable] => Integer
            [totalResultsReturned] => Integer
            [firstResultPosition] => Integer
            [0] => Array
                (
                    [Result] => Array
                        (
                            [Request] => Array
                                (
                                    [Query] => String
                                )

                            [Modules] =>  String
                            [0] => Array
                                (
                                    [Name] => String
                                    [Description] => String
                                    [Headline] => String
                                    [Url] => String
                                    [Availability] => String
                                    [Code] => String
                                    [PersonId] => String
                                    [ProductId] => String
                                    [Image] => Array
                                        (
                                            [Id] => String
                                            [Small] => String
                                            [Medium] => String
                                        )
                                )
原因

エラー内容はStringなのにオフセットに配列つかうんじゃねえ
つまり文字列を対象に3次元配列としてアクセスしちゃうとPHP4ではなんもしないもに
PHP5ではエラーになっちゃうってことですね。
ようは ResultSet->0->Result でループをぶん回すと (Array)Request とか (String)Modules
とかがまざっちゃうわけですねハイ。
おそらくこのゴミも全部foreachかけてるのが原因ぽい。

一応ぐぐったらこんなのも出てきた。
https://www.zend.com/forums/index.php?t=msg&th=1556&S=c38b4b1a45a1dfba92db79dd967cc302

つまるとここういうこと
$array['hoge'] = "nemu";

print($array['hoge'][1]);
//e が表示される

print($array['hoge'][1][1]);
//PHP4だと何も表示されない
//PHP5だとcannot use string offset as an array
対応策

issetなりis_arrayなりで$v[‘Image’]がある配列だけ作業するようにするのが
一番無難かな。

$unserializedData = unserialize(file_get_contents('http://shopping.yahooapis.jp/ShoppingWebService/V1/php/itemSearch?'));

foreach ($unserializedData['ResultSet'][0]['Result'] as $k=>$v) {
    if (is_array($v['Image'])) {
        print($v['Image']['Medium']);
    }
}

結局

配列とハッシュをごちゃごちゃにまとめるんじゃねえってかんじかな。。
せめて

[Result] => Array
    (
        [Request] => Array
            (
                [Query] => String
            )

        [Modules] =>  String
        [resultData] => Array (
                                [0] => array
                                [1] => array
                              )

こうしてほしいな。
絶対みんなここをforeachすんだから無駄な情報は移動しておいてほしいわ。。。


Leave a Reply