【问题标题】:Appending new data to object将新数据附加到对象
【发布时间】:2018-10-15 18:34:48
【问题描述】:

我一直在尝试将新数据附加到我为 AMchart 创建的 stdClass 对象

我从数据库中返回我想要的所有行,然后创建一个新对象并循环遍历返回的数组,但不是将我想要的内容附加到现有对象的末尾,而是被覆盖。 PHP 对象没有 append 或 push 方法,那么如何实现呢?

这是我的代码的样子。我错过了一些简单的东西吗?

    $sql = 'SELECT 
            count(*) as clients,
            STR_TO_DATE(Appt_date, \'%m/%d/%Y\') AS date,
            SUM(wait_time) as total_wait_time
            FROM tb_by_client
            WHERE status = @qualifier
            GROUP BY Appt_date';

    $rows = $db->fetchAll($sql);
    $chartObject = new stdClass();
    foreach($rows as $row){
        $row->average = round($row->total_wait_time / $row->clients);
        $chartObject->date = $row->date;
        $chartObject->average = $row->average;
    }
    $chartArray[] = $chartObject;
    return json_encode($chartArray);

所以不要得到看起来像这样的东西

[{"date":"2018-10-01","average":12},{"date":"2018-10-02","average":-33},{"date":"2018-10-04","average":23},{"date":"2018-10-05","average":6}]

我只回来一个

[{"date":"2018-10-01","average":12}]

因为每个循环都会覆盖最后一个键和值

您如何改为追加?

【问题讨论】:

  • $chartArray[] = $chartObject; 需要在您的循环中
  • 还有$chartObject = new stdClass(); :)

标签: php json object


【解决方案1】:

你的问题是你覆盖了数据而不保存它

$chartObject = new stdClass();
foreach($rows as $row){
    $row->average = round($row->total_wait_time / $row->clients);
    $chartObject->date = $row->date;
    $chartObject->average = $row->average;
}
$chartArray[] = $chartObject;

查看foreach($rows as $row){ 的每次迭代,您更改了$chartObject 中的数据,但您从未保存在$chartArray 中。

改为这样做

foreach($rows as $row){
    $chartObject = new stdClass(); //new instance of stdClass, obj pass by refrence
    $row->average = round($row->total_wait_time / $row->clients);
    $chartObject->date = $row->date;
    $chartObject->average = $row->average;
    $chartArray[] = $chartObject;
}

就我个人而言,我什至不会费心使用对象:

foreach($rows as $row){
    $average = round($row->total_wait_time / $row->clients);
    $chartArray[] = ['date'=>$row->date,'average'=>$average];
}

当您使用字符串键对数组进行 JSON 编码时,它将使其成为正确的 Javascript 对象结构。所以真的没有必要把所有这些对象都保存在内存中,而且代码更小、更干净、更容易阅读。

我在代码中暗示的最后一件事是,对象在 PHP 中是通过引用传递的(现在),如果您不为每次迭代创建对象的新实例,您实际上会将所有引用更新为物体。可以这样说明:

$obj = new stdClass;

$objects = [];

for($i=0;$i<3;++$i){
    $obj->foo = $i;
    $objects[] = $obj;
    print_r($objects);
}

输出:

Array
(
    [0] => stdClass Object
        (
            [foo] => 0
        )

)
Array
(
    [0] => stdClass Object
        (
            [foo] => 1
        )

    [1] => stdClass Object
        (
            [foo] => 1
        )

)
Array
(
    [0] => stdClass Object
        (
            [foo] => 2
        )

    [1] => stdClass Object
        (
            [foo] => 2
        )

    [2] => stdClass Object
        (
            [foo] => 2
        )

)

Sanbox

每个数组都是for 循环的一次迭代,这是同一个数组,每次迭代后都添加了另一行。

如您所见,每个副本(它不是真正的副本)都通过数组中的引用进行更新。基本上我们已经存储了同一个对象(实例,将调用他Bob)3次,而不是3个单独的对象(BobAliceJohn)。

如果您存储的数据是个人衬衫的颜色,当Bob 穿上一件红色衬衫时,他也穿上了一件红色衬衫,但AliceJohn 没有。

因此,您需要为每次迭代创建对象的新实例并存储它。

希望有帮助!

【讨论】:

  • 感谢您的澄清,尽管 Nigel Ren 只需编辑查询即可获得快捷方式,但我很感激您花时间告诉我哪里出错了。谢谢!
【解决方案2】:

您可以在 SQL 中进行数学运算,它会完全切断循环...

   $sql = 'SELECT STR_TO_DATE(Appt_date, \'%m/%d/%Y\') AS date,
            round(SUM(wait_time)/count(*)) as average
            FROM tb_by_client
            WHERE status = @qualifier
            GROUP BY Appt_date';

    return json_encode($db->fetchAll($sql));

【讨论】:

  • 我什至没有看SQL ...大声笑。比如我什至没有注意到原来的里面有group by。在编写问题时,使用 SQL 而不是 PHP 更有意义。不错的答案!
  • 你是对的,这样就简单多了。我什至没有想过从那个角度接近它,感谢您的提醒!
【解决方案3】:

你误解了什么应该在循环中,什么不应该。

这应该没问题:

$sql = 'SELECT 
        count(*) as clients,
        STR_TO_DATE(Appt_date, \'%m/%d/%Y\') AS date,
        SUM(wait_time) as total_wait_time
        FROM tb_by_client
        WHERE status = @qualifier
        GROUP BY Appt_date';

$rows = $db->fetchAll($sql);
$chartArray = [];
foreach($rows as $row){
    $row->average = round($row->total_wait_time / $row->clients);
    $chartObject = new stdClass();
    $chartObject->date = $row->date;
    $chartObject->average = $row->average;
    $chartArray[] = $chartObject;
}
return json_encode($chartArray);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-06
    • 2016-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 2019-07-06
    • 2017-08-05
    相关资源
    最近更新 更多