100

私はjson_decode()次のようなものを使用しています:

$myVar = json_decode($data)

これにより、次のような出力が得られます。

[highlighting] => stdClass Object
        (
            [448364] => stdClass Object
                (
                    [Data] => Array
                        (
                            [0] => Tax amount liability is ....... 

キー[0]の文字列値にアクセスしたい。私が次のようなことをしようとすると:

print $myVar->highlighting->448364->Data->0;

このエラーが発生します:

解析エラー:構文エラー、予期しないT_DNUMBER

そこにある2つの数字/整数は問題があるようです。

4

7 に答える 7

305

PHP7.2用に更新

PHP 7.2では、オブジェクトと配列のキャストで数値キーを変換する際の動作が変更されました。これにより、この特定の不整合が修正され、以下のすべての例が期待どおりに動作するようになります。

混乱することが1つ少なくなります!


元の回答(7.2.0より前のバージョンに適用)

PHPには、あなたが本当に自分の中にいることを望まない暗い路地のシェアがあります。名前が数字のオブジェクトプロパティはその1つです...

彼らがあなたに決して言わなかったこと

事実#1:正当な変数名ではない名前のプロパティに簡単にアクセスすることはできません

$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->123foo; // error

事実#2:中括弧構文を使用してこのようなプロパティにアクセスできます

$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->{'123foo'}; // OK!

事実#3:ただしプロパティ名がすべて数字の場合は違います。

$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->{'123foo'}; // OK!
echo $o->{'123'}; // error!

実例

事実#4:そもそも、オブジェクトが配列からのものでない限り。

$a = array('123' => '123');
$o1 = (object)$a;
$o2 = new stdClass;
$o2->{'123'} = '123'; // setting property is OK

echo $o1->{'123'}; // error!
echo $o2->{'123'}; // works... WTF?

実例

かなり直感的です、あなたは同意しませんか?

あなたにできること

オプション#1:手動で行う

最も実用的なアプローチは、関心のあるオブジェクトを配列にキャストして戻すことです。これにより、プロパティにアクセスできるようになります。

$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
$a = (array)$o;
echo $o->{'123'}; // error!
echo $a['123']; // OK!

残念ながら、これは再帰的には機能しません。したがって、あなたの場合、次のようなことをする必要があります。

$highlighting = (array)$myVar->highlighting;
$data = (array)$highlighting['448364']->Data;
$value = $data['0']; // at last!

オプション#2:核オプション

別のアプローチは、オブジェクトを再帰的に配列に変換する関数を作成することです。

function recursive_cast_to_array($o) {
    $a = (array)$o;
    foreach ($a as &$value) {
        if (is_object($value)) {
            $value = recursive_cast_to_array($value);
        }
    }

    return $a;
}

$arr = recursive_cast_to_array($myVar);
$value = $arr['highlighting']['448364']['Data']['0'];

ただし、これが全体的に優れたオプションであるとは確信していません。これは、関心のないすべてのプロパティと関心のあるプロパティを不必要に配列にキャストするためです。

オプション#3:賢くプレイする

前のオプションの代わりに、組み込みのJSON関数を使用することもできます。

$arr = json_decode(json_encode($myVar), true);
$value = $arr['highlighting']['448364']['Data']['0'];

JSON関数は、外部関数を定義することなく、配列への再帰的な変換を実行するのに役立ちます。これがどのように見えるかは、オプション#2の「核」の欠点に加えて、オブジェクト内に文字列がある場合、それらの文字列をUTF-8でエンコードする必要json_encodeがあるという欠点があります(これはの要件です)。

于 2012-04-26T12:16:18.673 に答える
11

ジョンの雄弁な説明に、これが失敗する理由を追加したかっただけです。これはすべて、配列を作成するときに、phpがキーを整数に変換するためです(可能な場合)。これにより、テンキーが保持されているという理由だけで、オブジェクトにキャストされた配列でルックアップの問題が発生します。すべてのプロパティアクセスオプションは文字列を予期または変換するため、これは問題があります。これは、次の手順で確認できます。

$arr = array('123' => 'abc');
$obj = (object) $arr;
$obj->{'123'} = 'abc';
print_r( $obj );

どちらが出力されますか:

stdClass Object ( 
  [123] => 'abc', 
  [123] => 'abc'
)

したがって、オブジェクトには2つのプロパティキーがあります。1つは数値(アクセスできません)で、もう1つは文字列ベースです。これがJonが機能する理由#Fact 4です。中括弧を使用してプロパティを設定すると、数値ではなく文字列ベースのキーを常に定義することになります。

Jonのソリューションを採用しましたが、それを頭に入れて、次のようにすることで、常に文字列ベースのキーを持つ配列からオブジェクトを生成できます。

$obj = json_decode(json_encode($arr));

この方法でアクセスすると、中括弧内の値が常に文字列に変換されるため、今後は次のいずれかを使用できます。

$obj->{123};
$obj->{'123'};

古き良き非論理的なPHP..。

于 2013-03-08T23:28:10.477 に答える
2

PHP7の場合

プロパティ名として番号を持つオブジェクトプロパティへのアクセス。配列をオブジェクトにキャストした後に主に必要になります。

    $arr = [2,3,7];
    $o = (object) $arr;

    $t = "1";
    $t2 = 1;
    $t3 = (1);

    echo $o->{1};      // 3
    echo $o->{'1'};   // 3
    echo $o->$t;        // 3
    echo $o->$t2;       // 3
    echo $o->$t3;       // 3

    echo $o->1;       // error
    echo $o->(1);      // error
于 2019-08-03T08:32:11.527 に答える
1

この関数をネットからコピーしました。それが言うように機能する場合(「stdClassオブジェクトを多次元配列に変換する関数」)、次のことを試してください。

<?php

    function objectToArray($d) {
        if (is_object($d)) {
            // Gets the properties of the given object
            // with get_object_vars function
            $d = get_object_vars($d);
        }

        if (is_array($d)) {
            /*
            * Return array converted to object
            * Using __FUNCTION__ (Magic constant)
            * for recursive call
            */
            return array_map(__FUNCTION__, $d);
        }
        else {
            // Return array
            return $d;
        }
    }

?>
  • 最初に配列をobjectToArray関数に渡します
  • その後、戻り値を取ります
  • エコー[highlighting][448364][Data][0]

ソース:PHPstdClassからArrayおよびArrayからstdClass

于 2012-04-26T12:14:15.593 に答える
1

オブジェクトが次のように始まる場合@

SimpleXMLElement Object (
    [@attributes] => Array (
        [href] => qwertyuiop.html
        [id] => html21
        [media-type] => application/xhtml+xml
    )
)

使用する必要があります:

print_r($parent_object->attributes());

なぜなら、$parent_object->{'@attributes'}または機能し$parent_object['@attributes']ないからです。

于 2016-11-06T14:58:57.603 に答える
1

ジョンの包括的な答えの最後の選択肢:

2番目のパラメーターをtrueに設定してjson_decode()を使用するだけです。

$array = json_decode($url, true);

これにより、オブジェクトではなく連想配列が返されるため、事後に変換する必要はありません。

これはすべてのアプリケーションに適しているわけではありませんが、元のオブジェクトのプロパティを簡単に参照するのに非常に役立ちました。

このチュートリアルで解決策が見つかりました-http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP/

よろしく

于 2017-10-27T06:52:30.890 に答える
0

恐れ入りますが、数字で始まるオブジェクトに名前を付けることは許可されていません。最初の名前を文字で始まる「448364」に変更します。

2つ目は配列で、次のように角かっこでアクセスします。

print myVar->highlighting->test_448364->Data[0]

代わりは

于 2012-04-26T12:09:37.773 に答える