PHP是否允许在stdObject中包含重复的属性?

时间:2016-08-25 03:07:01

标签: php drupal

我遇到了一个非常奇怪的错误。我有一个名为$ 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"
}

请注意,标题键与不同的值重复。在这种情况下是否有任何条件可能发生?

1 个答案:

答案 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";

使用密钥上的foreachvar_dump输出,会显示此内容......

string(6) "title"
string(5) "title"

注意一个是string长度6,另一个是长度为5的字符串。

盐粒

在尝试调试变量时使用var_dump总是比使用print_r之类的更好,因为var_dump是专为调试目的而设计的,而print_r只是一个递归打印(因此名称)。打印nullfalse或空字符串等值不会为调试提供有用的信息,但var_dump会这样做。