29

文字列型として数値キーを持つ PHP 配列があります。

しかし、それらにアクセスしようとすると、PHP で未定義のインデックス エラーが発生します。

$a = (array)json_decode('{"1":1,"2":2}');
var_dump($a);
var_dump(isset($a[1]));
var_dump(isset($a["1"]));
var_dump($a[1]);
var_dump($a["1"]);

出力:

配列 (サイズ=2)
    '1' => 整数 1
    '2' => 整数 2

ブール偽

ブール偽

エラー: E_NOTICE: 未定義のオフセット: 1

ヌル

エラー: E_NOTICE: 未定義のオフセット: 1

ヌル

これらの値にアクセスするにはどうすればよいですか?

デモ: http://codepad.viper-7.com/8O03IM

4

6 に答える 6

32

したがって、これに触れている他の回答は見たことがありませんが、@xdazz が近づいています。

環境を開始しましょう$obj。デコードされた文字列のオブジェクト表記に相当します。

php > $obj = json_decode('{"1":1,"2":2}');

php > print_r($obj);
stdClass Object
(
    [1] => 1
    [2] => 2
)

php > var_dump( $obj );
object(stdClass)#1 (2) {
  ["1"]=>
  int(1)
  ["2"]=>
  int(2)
}

文字列にアクセスしたい場合、以下は失敗することがわかっています。

php > echo $obj->1;

Parse error: parse error, expecting `T_STRING' or `T_VARIABLE' or `'{'' or `'$'' in php shell code on line 1

オブジェクト変数へのアクセス

次のようにアクセスできます。

php > echo $obj->{1};
1

これは、次のように言っているのと同じです:

php > echo $obj->{'1'};
1

配列変数へのアクセス

配列の問題は、次が空白を返すことです。これは型キャストの問題です。

php > echo $obj[1];
php >

型キャストを戻すと、オブジェクトに再びアクセスできるようになります。

php > $obj = (object) $obj;
php > echo $obj->{1};
1

上記を自動化する関数は次のとおりです。

function array_key($array, $key){
    $obj = (object) $array;
    return $obj->{$key};
}

使用例:

php > $obj = (array) $obj;
php > echo array_key($obj, 1);
1

php > echo array_key($obj, 2);
2
于 2012-09-13T01:51:17.190 に答える
26

配列が必要な場合は、json_decodeの 2 番目のパラメーターを に設定しtrueます。

$a = json_decode('{"1":1,"2":2}', true);

編集: std オブジェクトを配列にキャストすると、数値文字列キーは数値にキャストされません。ここに例があります。

$obj = new stdClass;
$obj->{'1'} = 1;
$arr = (array) $obj;
var_dump($arr);
var_dump(isset($arr[1]));
于 2012-07-17T03:19:03.060 に答える
15

どうやら、これは既知の問題であり、修正する予定はありません。Doc Bug # 45959オブジェクトから配列への変換により奇妙な動作が発生する:

パフォーマンスの低下を意味する修正であるため、既知の問題として保持する方がよいようですが、文書化されています。

このおかしさは、(その後)配列型のドキュメントに記載されています(強調は私のものです):

オブジェクトが配列に変換される場合、結果は要素がオブジェクトのプロパティである配列になります。キーはメンバ変数名ですが、いくつかの注目すべき例外があります:整数プロパティにはアクセスできません....これにより、予期しない動作が発生する可能性があります...

于 2012-07-17T03:28:20.827 に答える
1

最近同じ問題に遭遇しました。

$obj = new stdClass();
$obj->{'0'} = "test";

$array = (array)$obj;
foreach ($array as $key => $value) {
   $array[$key] = strtoupper($value);
}
var_dump($array);

このコードは次を出力します。

array(2) {
  ["0"]=>
  string(4) "test"
  [0]=>
  string(4) "TEST"
}

再帰的にオブジェクトを配列に変換するメソッドをデバッグしているときに気が狂いました。

于 2012-09-14T21:27:20.147 に答える
1

はい。PHPにはオブジェクトから配列への型キャストに問題がありますが、foreachはオブジェクトまたは連想配列をインテリジェントに処理しています。

$a = json_decode('{"1":1,"2":2}'); //need not typecast but doesnt break even if u typecast

foreach ($a as $k=>$v){
    echo $v;
}
于 2012-09-14T08:42:30.410 に答える