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

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

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

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

$obj -> $field[0];

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

我或多或少地尝试在 PHP 执行之前动态地编写它,以便它能够输出正确的值。对于如何解决这个问题有什么想法吗?

104699 次浏览

Update for PHP 7.0

PHP 7 introduced changes to how indirect variables and properties are handled at the parser level (see the corresponding RFC for more details). This brings actual behavior closer to expected, and means that in this case $obj->$field[0] will produce the expected result.

In cases where the (now improved) default behavior is undesired, curly braces can still be used to override it as shown below.

Original answer

Write the access like this:

$obj->{$field}[0]

This "enclose with braces" trick is useful in PHP whenever there is ambiguity due to variable variables.

Consider the initial code $obj->$field[0] -- does this mean "access the property whose name is given in $field[0]", or "access the element with key 0 of the property whose name is given in $field"? The braces allow you to be explicit.

I think you are looking for variable-variable type notation which, when accessing values from other arrays/objects, is best achieved using curly bracket syntax like this:

$obj->{field[0]}

The magic method __get is you friend:

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");
}
}

Usage:

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

Explanation: All your field data is stored in a array. As you access $myobj->myprop that property obviously does not exists in the class. That is where __get is called. __get looks up the name in the field array and returns the correct value.

I worked on some code that used dynamically created object properties. I thought that using dynamically created object properties was pretty cool (true, in my opinion). However, my program took 7 seconds to run. I removed the dynamic object properties and replaced them object properties declared as part of each class (public in this case). CPU time went from over 7 seconds to 0.177 seconds. That's pretty substantial.

It is possible that I was doing something wrong in the way I was using dynamic object properties. It is also possible that my configuration is broken in some way. Of course, I should say that I have a very plain vanilla PHP configuration on my machine.

today i face that challenge. I ended up with that style of development

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