You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP如何直接访问stdClass对象的整数键名公共属性

问题背景

我更倾向于使用对象语法访问关联数组,即相较于$arr['item_title']的数组下标访问写法,我更偏好使用$arr->item_title的对象属性访问写法。我编写了如下逻辑生成数组后,通过强制类型转换将其转换为对象:

public function getTotal()
{
    $total = 0;
    $items = [];
    $i = 0;
    $val = ($this->type == 'PUR')? 'cost': 'price';
    foreach($this->invoiceItems as $item){
        $items[$i]['item_title'] = $item->item->title;
        $items[$i]['item_id']    = $item->item_id;
        $items[$i]['unit_title'] = $item->unit->title;
        $items[$i]['unit_id']    = $item->unit_id;
        $items[$i]['cost']       = $item->itemUnit->cost;
        $items[$i]['price']      = $item->itemUnit->price;
        $items[$i]['qty']        = $item->qty;
        $total = $total + ($item->qty*$item->itemUnit->${'val'}) ;
        $i++;
    }
    $output['total'] = $total;
    $output['items'] = (object) $items;
    $this->setTotal((object) $output);
    return $this->_total;
}

转换完成后生成的对象结构示例如下(通过var_dump打印输出):

<?= var_dump($model->total->items);?>

object(stdClass)[117]
  public '0' => 
    array (size=7)
      'item_title' => string 'Aspoceed tab.' (length=13)
      'item_id' => int 2
      'unit_title' => string 'Packet2s-10' (length=11)
      'unit_id' => int 3
      'cost' => float 9.25
      'price' => float 10
      'qty' => int 2
  public '1' => 
    array (size=7)
      'item_title' => string 'Aspoceed tab.' (length=13)
      'item_id' => int 2
      'unit_title' => string 'Strip10' (length=7)
      'unit_id' => int 2
      'cost' => float 4.75
      'price' => float 5.25
      'qty' => int 1
  public '2' => 
    array (size=7)
      'item_title' => string 'Apidone' (length=7)
      'item_id' => int 3
      'unit_title' => string 'Bottle Pack 12' (length=14)
      'unit_id' => int 6
      'cost' => float 118
      'price' => float 121.75
      'qty' => int 2

遇到的问题

无法在不通过循环遍历的前提下直接访问上述对象的公共属性,尝试以下几种访问写法均返回错误:

$model->total->items->['0']->item_title
// OR
$model->total->items->[0]->item_title
// OR
$model->total->items[0]->item_title
// OR
$model->total->items['0']->item_title

核心疑问:是否可以直接访问通过上述方式创建的对象?如果可以,正确的访问写法是什么?

解答

可以直接访问该方式创建的对象,之前访问失败有两个核心原因:

  • 数字索引数组强转为stdClass对象后,数字键名会成为对象的公开属性,但这类数字命名的属性无法直接通过->后跟字面量数字/字符串数字的方式读取,必须用花括号包裹键名的特殊语法访问
  • 现有结构中0/1/2这类属性对应的值仍然是数组类型,不是对象,因此读取到该层级后,需要用数组下标语法访问子元素,不能直接用->调用属性

现有结构的正确访问写法

// 访问第一条数据的item_title字段
$model->total->items->{0}['item_title'];
// 字符串格式数字键名写法效果完全一致
$model->total->items->{'0'}['item_title'];

统一对象语法访问的优化方案

如果需要全程使用对象属性语法访问所有层级,可以在生成子项时就将每个子项数组也强制转换为对象,修改原循环内的赋值逻辑即可:

foreach($this->invoiceItems as $item){
    $items[$i] = (object)[
        'item_title' => $item->item->title,
        'item_id'    => $item->item_id,
        'unit_title' => $item->unit->title,
        'unit_id'    => $item->unit_id,
        'cost'       => $item->itemUnit->cost,
        'price'      => $item->itemUnit->price,
        'qty'        => $item->qty
    ];
    $total = $total + ($item->qty*$item->itemUnit->${'val'}) ;
    $i++;
}

修改完成后所有层级均为stdClass对象,可统一用对象语法访问:

$model->total->items->{0}->item_title;

内容的提问来源于stack exchange,提问作者SaidbakR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 07:48:32