我遇到了一个非常奇怪的错误。我有一个名为$ row的对象,如下所示:
stdClass Object
(
[title] => Some Title
[body] => My body
[topic] => Topic
[dataType] => Survey
[csvrownum] => 1
)
我只是试图以下列方式打印出title属性:
print_r($row->title);
然而由于某些原因,它不输出任何东西。
然后我尝试手动设置title属性并在之后打印,如下所示:
$row->title = 'My Title';
print_r($row->title);
令人惊讶的是它有效但为什么?为了使这更奇怪,我决定在手动设置title变量之后var_dump对象:
$row->title = 'My Title';
var_dump($row);
这就是我所拥有的:
class stdClass#391 (6) {
public $title =>
string(3) "Some title"
public $body =>
string(7) "My body"
public $topic =>
string(6) "Topic"
public $dataType =>
string(17) "Survey"
public $csvrownum =>
int(1)
public $title =>
string(8) "My title"
}
请注意,标题键与不同的值重复。在这种情况下是否有任何条件可能发生?
答案 0 :(得分:4)
不,PHP不允许对象具有重复的属性名称,因为PHP中的对象就像数组一样实现。它们都被实现为有序的哈希映射。在散列映射中,两个具有相同散列的东西会相互覆盖。
您可能只在对象属性名称中包含不可抑制的字符。为了调试目的,您可以通过执行以下操作来更清楚地看到这一点......
foreach($row as $key => $value) {
var_dump($key);
}
例如,如果我们有这样的对象,你会看到它被覆盖。
$row = new stdClass;
$row->title = "First";
$row->title = "Second";
但是这样的事情可能更具欺骗性......
$row = new stdClass;
$row->{"title\0"} = "First";
$row->title = "Second";
使用密钥上的foreach
从var_dump
输出,会显示此内容......
string(6) "title" string(5) "title"
注意一个是string
长度6
,另一个是长度为5
的字符串。
在尝试调试变量时使用var_dump
总是比使用print_r
之类的更好,因为var_dump
是专为调试目的而设计的,而print_r
只是一个递归打印(因此名称)。打印null
,false
或空字符串等值不会为调试提供有用的信息,但var_dump
会这样做。