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


81

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

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

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

$obj -> $field[0];

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

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

Answers:


205

PHP 7.0更新

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

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

原始答案

这样写访问:

$obj->{$field}[0]

只要变量变量有歧义,此“用大括号括起来”的技巧就在PHP中很有用。

考虑一下初始代码$obj->$field[0]-这是否意味着“访问名称是在属性中的属性$field[0]”,还是“使用0名称是在属性中的属性的键访问元素$field?” 大括号可以让您显得清晰。


这个原始语句在我的代码中有效: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]“
jumpjack

31

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

$obj->{field[0]}

12

魔术方法__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数组中查找名称并返回正确的值。


3
不要这样 __get函数是性能消耗,除了会产生一些意料之外的严重问题外,还应尽可能避免使用它们。此示例特别可怕,因为它引发异常,如果开发人员不打算访问不存在的属性以引发异常,则该异常可能导致严重的应用中断行为,从而将简单的属性访问转换为潜在的致命错误。
moberemk

0

aboulfazl,因为与该类同名的PHP 5.3.3方法将不被视为构造函数!

    YourClass
    {
        public $any = false;

        public function __construct($any = null)
        {
            $this->any = (is_null($any) ? $this->any : $any);
        }
    }

这可行,但是主题所有者没有问,乔恩给了遮阳篷!


0

我编写了一些使用动态创建的对象属性的代码。我认为使用动态创建的对象属性非常酷(我认为是正确的)。但是,我的程序需要7秒钟才能运行。我删除了动态对象属性,并将它们替换为声明为每个类的一部分的对象属性(在本例中为public)。CPU时间从7秒钟以上变为0.177秒。那是相当可观的。

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


0

今天,我面临着挑战。我最终得到了这种发展风格

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

-4

您可以使用PHP默认类Object的实例向其动态分配属性的最佳方法

$inst=new \StdClass;
$inst->any_property = '';

-6

具有继承性。例如:

YourClass extends stdClass {
   public function YourClass() {
      $this->AnyProperty="any";
   }
}

现在,可以动态声明AnyProperty。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.