97

我的代码中有如下所示的对象属性:

$obj ->field_name_cars[0];
$obj ->field_name_clothes[0];

问题是我有 100 个字段名称,需要动态编写属性名称。否则,对象名称和属性的键将始终相同。所以我尝试了:

$obj -> $field[0];

希望属性的名称会动态更改并访问正确的值。但是,我不断在 stdClass::$field 中得到 'undefined property $field;

或多或少我正在尝试在执行之前动态编写php,以便它可以输出正确的值。关于如何解决这个问题的想法?

4

5 回答 5

242

PHP 7.0 更新

PHP 7对在解析器级别处理间接变量和属性的方式进行了更改(有关更多详细信息,请参阅相应的 RFC)。这使实际行为更接近预期,并意味着在这种情况下$obj->$field[0]将产生预期结果。

在不需要(现在改进的)默认行为的情况下,仍然可以使用花括号来覆盖它,如下所示。

原始答案

像这样编写访问权限:

$obj->{$field}[0]

这种“用大括号括起来”的技巧在 PHP 中非常有用,只要由于变量变量而存在歧义。

考虑初始代码$obj->$field[0]——这是否意味着“访问名称在”中给出的属性,或者“使用名称在”中给出的属性的$field[0]键访问元素?大括号允许您明确表达。0$field

于 2012-09-24T19:07:23.597 回答
36

我认为您正在寻找变量-变量类型表示法,当从其他数组/对象访问值时,最好使用像这样的大括号语法来实现:

$obj->{field[0]}
于 2012-09-24T19:08:01.497 回答
11

神奇的方法 __get 是你的朋友:

class MyClass
{
   private $field = array();

   public function __get($name)
   {
      if(isset($this->field[$name]))
        return $this->field[$name];
      else
        throw new Exception("$name dow not exists");
   }
}

用法:

$myobj = new MyClass();
echo $myobj->myprop;

说明:您所有的字段数据都存储在一个数组中。当您访问$myobj->myprop该属性时,该类显然不存在。这就是__get所谓的。在数组__get中查找名称并返回正确的值。field

于 2012-09-24T19:09:36.323 回答
3

今天我面临这一挑战。我最终采用了这种开发方式

$countTickets = new \stdClass;

foreach ($tickets as $key => $value) {

    if(!isset($countTickets->total)){
        $countTickets->total = 0;
    }

    if(!isset($countTickets->{$value['categoryname']})){
        $countTickets->{$value['categoryname']} = 0;
    }

    $countTickets->total += $value['number'];
    $countTickets->{$value['categoryname']} += $value['number']; 
}
于 2020-03-08T12:16:21.543 回答
0

我处理了一些使用动态创建的对象属性的代码。我认为使用动态创建的对象属性非常酷(在我看来是真的)。但是,我的程序需要 7 秒才能运行。我删除了动态对象属性并将它们替换为声明为每个类的一部分的对象属性(在本例中为公共)。CPU 时间从超过 7 秒变为 0.177 秒。这是相当可观的。

我在使用动态对象属性的方式上可能做错了什么。我的配置也可能以某种方式损坏。当然,我应该说我的机器上有一个非常简单的普通 PHP 配置。

于 2019-02-11T04:04:42.153 回答