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

发布于 2024-12-19 13:54:18 字数 1396 浏览 0 评论 0原文

我正在尝试将数据导出到分析中,但我做错了。

基本上我有一个包含 1 到 9 个主题的报告。 我正在从头开始编写这个导出工具,数据来自遗留系统。

分析应导出为 CSV,其中包含以下列:

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

我尝试过< code>foreach - 遍历报告主题数组并保持计数:

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

更新 因为我可能不会在箭头运算符的右侧使用变量,所以我将其重写为一个非常不干燥的开关:

$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)对象。

我希望任何人都能找到缺陷并​​指出我的实施方向。它背后的哲学加分,这样我不仅可以帮助解决这个问题,而且可以更好地理解 oop-php 世界。

I am trying to export data into an analysis but I'm doing something wrong.

Basically I have a report that has between 1 and 9 subjects.
I am writing this export-tool from scratch, the data is from a legacy system.

The analysis should be exported as CSV, with columns like:

'report_id';'subject0';'subject1'...all the way to 'subject9'

I tried foreach-ing over an array of subjects of a report, and keeping count:

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

Update
Because I may not use variables on the right side of the arrow operator, I've rewritten it as a very un-DRY switch:

$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] is an object that stores strings as follows:
$this->analysis [$report_id] ->subject0 = "foo"
The $report_id is a result of an earlier loop.
$this->analysis is an array filled with (report)objects that are included in the analysis.

I hope that anyone can find the flaw and point me in the direction of DRY-ing up my implementation. Bonus points for the philosophy behind it, so that I'm not only helped with this problem, but have a better understanding of the oop-php world.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏了南城 2024-12-26 13:54:19

我不知道 $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?
  }
}

用变量来表示变量变量
文档:- http://php.net/manual/en/language.variables。变量.php

I have no idea where the $report_id come from ...
Usually, I will do this :-

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

make use of variable to represent variable variable
docs :- http://php.net/manual/en/language.variables.variable.php

只为守护你 2024-12-26 13:54:19

根据评论:您需要向其对象位于 $this->analysis [$report_id] 中的类添加一个神奇的 __set() 。为了方便起见,我们将该类称为 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”存储在带有键 barHelloWorld::$data 数组中。当然现在这个:

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

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

Based on the comments: You need to add a magic __set() to the class whose objects live in $this->analysis [$report_id]. Let's call the class HelloWorld for convenience. Your code would be something like:

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

}

The combination of a magic setter and getter essentially provides dynamic class properties via property overloading. So now you can do this:

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

Where "foobar" is stored in the HelloWorld::$data array with key bar. And of course now this:

$iterator=0;
foreach ($subjects as $subject) {
    $property = "subject{$iterator}";

    $this->analysis[$report_id]->$property = $subject;
    $iterator++;
}

should work fine. If the $subjects array's keys are ordered integers, you could also rewrite as:

foreach ($subjects as $iterator => $subject) {
    $property = "subject{$iterator}";

    $this->analysis[$report_id]->$property = $subject;
}

The two essential manual pages to understand the above are:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文