我得到一个奇怪的PHP错误后更新我的PHP版本到5.4.0-3。
我有这样一个数组:
Array
(
[host] => 127.0.0.1
[port] => 11211
)
当我试图像这样访问它时,我会得到奇怪的警告
print $memcachedConfig['host'];
print $memcachedConfig['port'];
Warning: Illegal string offset 'host' in ....
Warning: Illegal string offset 'port' in ...
我真的不想只是编辑我的php.ini并重新设置错误级别。
错误非法字符串偏移'whatever'在…通常意味着:你试图使用一个字符串作为一个完整的数组。
这实际上是可能的,因为字符串在php中可以被视为单个字符的数组。所以你认为$var是一个带键的数组,但它只是一个带标准数字键的字符串,例如:
$fruit_counts = array('apples'=>2, 'oranges'=>5, 'pears'=>0);
echo $fruit_counts['oranges']; // echoes 5
$fruit_counts = "an unexpected string assignment";
echo $fruit_counts['oranges']; // causes illegal string offset error
你可以在这里看到它的作用:
http://ideone.com/fMhmkR
对于那些遇到这个问题试图将错误的模糊性转化为解决它的方法的人,就像我一样。
你试图访问一个字符串,就好像它是一个数组,键是一个字符串。字符串不会理解这一点。在代码中,我们可以看到问题:
"hello"["hello"];
// PHP Warning: Illegal string offset 'hello' in php shell code on line 1
"hello"[0];
// No errors.
array("hello" => "val")["hello"];
// No errors. This is *probably* what you wanted.
在深度上
让我们看看这个错误:
警告:非法字符串偏移'端口'在…
上面写了什么?它说我们试图使用字符串'port'作为字符串的偏移量。是这样的:
$a_string = "string";
// This is ok:
echo $a_string[0]; // s
echo $a_string[1]; // t
echo $a_string[2]; // r
// ...
// !! Not good:
echo $a_string['port'];
// !! Warning: Illegal string offset 'port' in ...
这是什么原因造成的?
出于某种原因,你希望得到一个数组,但你得到了一个字符串。只是搞错了。也许你的变量被改变了,也许它从来都不是一个数组,这真的不重要。
我们能做些什么呢?
如果我们知道我们应该有一个数组,我们应该做一些基本的调试,以确定为什么我们没有数组。如果我们不知道是数组还是字符串,事情就变得有点棘手了。
我们可以做的是各种检查,以确保我们没有关于is_array和isset或array_key_exists的通知,警告或错误:
$a_string = "string";
$an_array = array('port' => 'the_port');
if (is_array($a_string) && isset($a_string['port'])) {
// No problem, we'll never get here.
echo $a_string['port'];
}
if (is_array($an_array) && isset($an_array['port'])) {
// Ok!
echo $an_array['port']; // the_port
}
if (is_array($an_array) && isset($an_array['unset_key'])) {
// No problem again, we won't enter.
echo $an_array['unset_key'];
}
// Similar, but with array_key_exists
if (is_array($an_array) && array_key_exists('port', $an_array)) {
// Ok!
echo $an_array['port']; // the_port
}
isset和array_key_exists之间有一些细微的区别。例如,如果$array['key']的值为空,则isset返回false。Array_key_exists会检查键是否存在。
从PHP 5.4开始,我们需要传递与函数预期相同的数据类型值。例如:
function testimonial($id); // This function expects $id as an integer
当调用这个函数时,如果一个字符串值是这样提供的:
$id = $array['id']; // $id is of string type
testimonial($id); // illegal offset warning
这将生成一个非法偏移警告,因为数据类型不匹配。为了解决这个问题,你可以使用settype:
$id = settype($array['id'],"integer"); // $id now contains an integer instead of a string
testimonial($id); // now running smoothly