我有一个数组和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)
答案 0 :(得分:25)
请参阅本节有关将对象转换为PHP Manual中的数组:
的信息键是成员变量名,但有一些值得注意的例外: 整数属性不可访问 ;私有变量的类名前置于变量名;受保护的变量在变量名前面加上'*'。
从PHP中的对象转换为数组时,整数数组键在内部存储为字符串。当您在PHP中访问数组元素或正常使用数组时,包含有效整数的键将自动转换为整数。内部存储为字符串的整数是一个无法访问的密钥。
注意区别:
$x = (array)json_decode('{"207":"test"}');
var_dump(key($x)); // string(3) "207"
var_dump($x);
// array(1) {
// ["207"]=>
// string(4) "test"
// }
$y['207'] = 'test';
var_dump(key($y)); // int(207)
var_dump($y);
// array(1) {
// [207]=>
// string(4) "test"
// }
这两个数组上的print_r提供相同的输出,但使用var_dump可以看出差异。
以下是一些可以重现您确切问题的代码:
$output = (array)json_decode('{"207":"sdf","210":"sdf"}');
print_r($output);
echo $output[207];
echo $output["207"];
简单的解决方法是将true
传递给json_decode以获取可选的assoc
参数,以指定您希望数组不是对象:
$output = json_decode('{"207":"sdf","210":"sdf"}', true);
print_r($output);
echo $output[207];
echo $output["207"];
答案 1 :(得分:20)
当casting到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"]
之类的直接访问始终为converted到$array[207]
,但不存在。
因为您正在将json_decode()
上面的对象应用于类似
$json = '{"207":"sdf", "210":"sdf"}'
最好的解决方案是首先避免使用数字键。这些可能更好地建模为对象数组的数字属性:
$json = '[{"numAttr":207, "strAttr":"sdf"}, {"numAttr":210, "strAttr":"sdf"}]'
这种数据结构与现在的数据结构相比有几个优点:
如果需要属性→对象图,可以快速获取它,例如:
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()
输出关联数组而不是对象,方法是将第二个参数设置为true
:
$map = json_decode($json, true);
对于您的输入数据,这直接产生
array(2) {
[207]=>
string(3) "sdf"
[210]=>
string(3) "sdf"
}
请注意,数组的键现在是整数而不是字符串。
我会考虑将JSON数据结构更改为更清晰的解决方案,尽管我知道可能无法这样做。
答案 2 :(得分:1)
我刚刚找到this bug,当通过调用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
答案 3 :(得分:1)
尝试
var_dump($output);
foreach ($output as $key => val) {
var_dump($key);
var_dump($val);
}
了解有关正在发生的事情的更多信息。
什么确切的行/声明会给你一个警告?
答案 4 :(得分:0)
你是如何打印阵列的?我建议print_r($arrayName);
接下来,您可以打印个别元素,例如:echo $arrayName[0];
答案 5 :(得分: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);
答案 6 :(得分:-1)
只需输入error_reporting(0);在你的方法或文件的开头。它将解决您的问题。