29

配列と PHP があり、それを印刷すると、アクセスする必要がある値が表示されますが、それらのキーでアクセスしようとすると、PHP 通知が表示されます。print_rで配列を印刷しました:

Array
(
    [207] => sdf
    [210] => sdf
)

インデックスを使用して配列にアクセスしようとすると、未定義のオフセット通知が表示されます。これが私のコードです:

print_r($output); 
echo $output[207];   // Undefined Offset
echo $output["207"]; // Undefined Offset

$output配列は、array_diff_keyへの呼び出しの結果であり、元々は HTTP POST 要求を介して JSON として入力されます。

array_keysから次のことがわかります。

Array
(
   [0] => 207
   [1] => 210
)

コメントへの応答:

var_dump(key($output));出力:

   string(3) "207"

var_dump(isset($output[key($output)]));出力:

   bool(false)
4

7 に答える 7

22

この問題は、有効な整数である文字列キーを持つオブジェクトにキャストするときに発生します。array

このオブジェクトがある場合:

object(stdClass)#1 (2) {
  ["207"]=>
  string(3) "sdf"
  ["210"]=>
  string(3) "sdf"
}

そして、あなたはそれをキャストします

$array = (array)$object

この配列を取得します

array(2) {
  ["207"]=>
  string(3) "sdf"
  ["210"]=>
  string(3) "sdf"
}

$array["207"]直接アクセス likeは常に存在しないに変換されるため、それらをループすることによってのみアクセスできるキーがあります。$array[207]

上記のようなオブジェクトを次のようなjson_decode()文字列に適用しているので

$json = '{"207":"sdf", "210":"sdf"}'

最善の解決策は、最初から数字キーを避けることです。これらはおそらく、オブジェクトの配列の数値プロパティとしてモデル化する方が適切です。

$json = '[{"numAttr":207, "strAttr":"sdf"}, {"numAttr":210, "strAttr":"sdf"}]'

このデータ構造には、現在のものよりもいくつかの利点があります。

  1. 数値プロパティを持つオブジェクトのコレクションとして、元のデータをよりよく反映します
  2. 他のプロパティで容易に拡張可能
  3. さまざまなシステム間での移植性が向上します (ご覧のとおり、現在のデータ構造は PHP で問題を引き起こしていますが、別の言語を使用すると、同様の問題に簡単に遭遇する可能性があります)。

プロパティ → オブジェクト マップが必要な場合は、次のようにすばやく取得できます。

function getNumAttr($obj) { return $obj->numAttr; } // for backward compatibility
$arr = json_decode($json); // where $json = '[{"numAttr":...
$map = array_combine(array_map('getNumAttr', $arr), $arr);

他の解決策は、 ascii-lime が提案したようにすることですjson_decode()。2番目のパラメーターをに設定することにより、オブジェクトの代わりに連想配列を強制的に出力しますtrue

$map = json_decode($json, true);

入力データの場合、これは直接生成します

array(2) {
  [207]=>
  string(3) "sdf"
  [210]=>
  string(3) "sdf"
}

配列のキーが文字列ではなく整数になっていることに注意してください。

ただし、JSON データ構造を変更することは、よりクリーンなソリューションであると考えていますが、そうできない可能性があることは理解しています。

于 2012-07-05T23:21:09.887 に答える
1

試す

var_dump($output);
foreach ($output as $key => val) {
    var_dump($key);
    var_dump($val);
}

何が起こっているかについてもっと学ぶために。

どのような正確な行/ステートメントが警告を投げていますか?

于 2012-06-18T20:52:22.397 に答える
1

unserializeの呼び出しによって配列が作成されると、PHP で配列要素にアクセスできなくなることがあるこのバグを発見しました。

次のスクリプトを含む (またはコマンド ラインから実行する) テスト PHP ファイルを作成します。

<?php 

$a = unserialize('a:2:{s:2:"10";i:1;s:2:"01";i:2;}'); 

print $a['10']."\n";

$a['10'] = 3; 
$a['01'] = 4; 

print_r($a);

foreach ($a as $k => $v) 
{ 
  print 'KEY: '; 
  var_dump($k); 
  print 'VAL: '; 
  var_dump($v); 
  print "\n"; 
}

エラーが発生した場合は、このバグのあるバージョンの PHP を使用しており、PHP 5.3 にアップグレードすることをお勧めします。

于 2012-06-18T20:15:28.377 に答える
0

アレイをどのように印刷しましたか?私は提案しますprint_r($arrayName);

次に、次のような個々の要素を印刷できます。echo $arrayName[0];

于 2012-06-18T20:16:20.907 に答える
0

私のアプローチを試してみてください:

class ObjectToArray {
    public static function convert( $object ) {
        if( !is_object( $object ) && !is_array( $object ) ) {
            return $object;
        }

        if( is_object( $object ) ) {
           $object = get_object_vars( $object );
        }

        return array_map( 'ObjectToArray::convert', $object );
    }
}

$aNewArray = ObjectToArray::convert($oYourObject);
于 2012-07-06T12:20:07.337 に答える