如何在对象上分配迭代属性/变量


How do I assign an iterating property/variable on an object?

我试图将数据导出到分析中,但我做错了什么。

基本上我有一个report,它有1到9个subject。我从头开始编写这个导出工具,数据来自遗留系统。

分析应导出为CSV,列如下:

'report_id';'subject0';'subject1'…一直到'subject9'

我尝试了foreach -ing一组报告的主题,并保持计数:

$iterator=0;
foreach ($subjects as $subject)
{
  $this->analysis [$report_id] ->subject${iterator} = (string)$subject;
  $iterator++;
}

因为我可能不会在箭头操作符的右侧使用变量,所以我将其重写为一个非常非dry的开关:

$iterator = 0;
foreach ($categories as $subject)
  {
    switch ($iterator)
    {
    case 0:
      $this->analysis [$report_id] ->subject0 =  $subject;
      break;
    case 1:
      $this->analysis [$report_id] ->subject1 =  $subject;
      break;
    case 2:
      $this->analysis [$report_id] ->subject2 =  $subject;
      break;
    // I have 6 more cases, just to fill all 9 subjects, snipped for brevity
    default:
      //some errorhandling //snipped for brevity
      break 2;
    } 
    $iterator++;
  } 

$this->analysis [$report_id]是一个对象,按如下方式存储字符串:
$this->analysis [$report_id] ->subject0 = "foo"
$report_id是前一个循环的结果。
$this->analysis是一个包含分析中包含的(report)对象的数组。

我希望任何人都能找到缺陷,并指出我dry - up实现的方向。它背后的哲学是加分项,因此我不仅帮助解决了这个问题,而且对oop-php的世界有了更好的理解。

我不知道$report_id来自哪里…
通常,我会这样做:-

$iterator = $i = 0;
foreach ($categories as $subject)
{
  $var = "subject{$i}";
  $this->analysis [$report_id]->$var =  $subject;
  ++$i;
  if ($i >= 10)
  {
    // what is your error?
  }
}

使用变量来表示变量
Docs:- http://php.net/manual/en/language.variables.variable.php

根据注释:您需要将一个magic __set()添加到其对象驻留在$this->analysis [$report_id]中的类中。为方便起见,我们称这个类为HelloWorld。你的代码应该是这样的:

class HelloWorld {
    private $data = array();
    public function __set($key, $value) {
        $this->data[$key] = $value;        
    }
    public function __get($key) {
        if( !array_key_exists($key, $this->data) ) {
            return null; // or throw an exception
        }
        return $this->data[$key];        
    }
}

魔法setter和getter的组合本质上通过属性重载提供了动态的类属性。现在你可以这样做:

$foo = new HelloWorld()
$foo->bar = "foobar";
echo $foo->bar;

其中"foobar"存储在HelloWorld::$data数组中,键为bar。当然还有这个:

$iterator=0;
foreach ($subjects as $subject) {
    $property = "subject{$iterator}";
    $this->analysis[$report_id]->$property = $subject;
    $iterator++;
}

应该可以正常工作。如果$subjects数组的键是有序的整数,您还可以重写为:

foreach ($subjects as $iterator => $subject) {
    $property = "subject{$iterator}";
    $this->analysis[$report_id]->$property = $subject;
}

了解上述内容的两个基本手册页是:

  • 魔法方法
  • 方法和属性重载和