如何动态编写PHP对象属性名称?

How do I dynamically write a PHP object property name?

提问人:user658182 提问时间:9/25/2012 最后编辑:j0kuser658182 更新时间:3/8/2020 访问量:114692

问:

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

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

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

$obj -> $field[0];

希望动态更改属性的名称并访问正确的值。但是,我一直在 stdClass::$field 中得到“未定义的属性$field;

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

PHP的

评论


答:

277赞 Jon 9/25/2012 #1

PHP 7.0 更新

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

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

原始答案

像这样编写访问权限:

$obj->{$field}[0]

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

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

评论

0赞 jumpjack 11/28/2019
这个原始语句在我的代码中有效:echo $json_dump->geometry[6]->obs[2]->hayabusa2->delay_from;但是我无法通过将“geometry[6]->obs[2]->hayabusa2->delay_from”分配给$path并使用 echo $json_dump->{$path} 来“模拟”它,我得到“未定义的属性:stdClass::$geometry[6]”
42赞 Mike Brant 9/25/2012 #2

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

$obj->{field[0]}
11赞 JvdBerg 9/25/2012 #3

神奇的方法__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__getfield

评论

4赞 moberemk 2/27/2015
别这样。__get函数是性能消耗者,除了通过意外行为造成一些严重问题之外,还应尽可能避免使用这些函数。这个例子特别可怕,因为它会引发一个异常,如果开发人员不打算访问一个不存在的属性来引发异常,那么这可能会导致严重的应用中断行为,从而将简单的属性访问变成潜在的致命错误。
-1赞 Peter Schaeffer 2/11/2019 #4

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

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

评论

0赞 ToolmakerSteve 12/1/2020
这个轶事可以通过显示一小段代码来改进。您的代码是否基于此处的答案之一?通过其他地方的信息,你可以提供链接?可能只需要一些单行代码。动态创建对象属性的示例。稍后引用该属性。此外,平均而言,您使用(引用)每个属性的次数是多少?您向一个对象添加了多少个动态属性?少于六个?超过20个?
4赞 Jordan Georgiadis 3/8/2020 #5

今天,我面临着这一挑战。我最终选择了这种开发风格

$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']; 
}