web-dev-qa-db-ja.com

整数のような名前でオブジェクトのプロパティにアクセスする方法は?

出力が次のPHPオブジェクトプロパティにアクセスする方法:

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

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

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

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

編集:

ここで、myVarの取得元について少し説明します。私はjson_decode()のようなものを使用しています:

$myVar = json_decode(url)
84
avinash shah

PHP 7.2用に更新

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

混乱することはもう一つありません!


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

PHPには、あなたが本当に自分自身を見つけたくない暗い路地があります。名前が数字であるオブジェクトプロパティはそれらの1つです...

彼らがあなたに言ったことはない

Fact#1:有効な変数名ではない名前のプロパティには簡単にアクセスできません

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

Fact#2:You can中括弧構文でそのようなプロパティにアクセスする

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

Fact#3:しかしnotプロパティ名がすべて数字の場合!

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

実例 .

Fact#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'];

しかし、これは、あなたがnotに興味があるプロパティだけでなく、あなたが興味を持っているすべてのプロパティを不必要に配列にキャストするので、これが全面的に優れたオプションであるとは確信していません。

オプション#3:それを賢く再生する

前のオプションの代替方法は、組み込みのJSON関数を使用することです。

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

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

274
Jon

ジョンの雄弁な説明に、これが失敗する理由を追加したかっただけです。配列を作成するときに、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 ...

10
Pebbl

Jonの包括的な答えの最後の選択肢:

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

$array = json_decode($url, true);

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

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

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

よろしく

1
Bluekable

この関数をネットからコピーしました。正常に機能する場合(「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関数に渡します
  • その後、戻り値を取得します
  • echo [highlighting][448364][Data][0]

ソース: PHP stdClass to ArrayおよびArray to stdClass

1
Ruwantha

PHP 7の場合

プロパティ名として数字を持つオブジェクトプロパティへのアクセス。ほとんどの場合、配列をオブジェクトにキャストした後に必要になります。

    $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
0
umesh kadam

数値で始まるオブジェクトに名前を付けることはできません。文字で始まる最初の名前を「448364」に変更します。

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

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

代わりに

0
Gustav

オブジェクトが@で始まる場合:

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']が機能しないためです。

0
Zydnar