Добавление новых данных к объекту - PullRequest
0 голосов
/ 15 октября 2018

Я застрял, пытаясь добавить новые данные в объект stdClass, который я создаю для AMchart

Я возвращаю все строки, которые хочу из БД, затем создаю новый объект и зацикливаюсьчерез возвращенный массив, но вместо добавления того, что я хочу, к концу существующего объекта, он просто перезаписывается.PHP-объекты не имеют метода добавления или добавления, так как же это сделать?

Вот как выглядит мой код.Я скучаю по чему-то простому?

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

Потому что каждыйцикл перезаписывает последний ключ и значение

Как вы добавляете вместо этого?

Ответы [ 3 ]

0 голосов
/ 15 октября 2018

Вы неправильно понимаете, что должно быть в цикле, а что нет.

Это должно быть хорошо:

$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);
0 голосов
/ 15 октября 2018

Вы можете сделать математику в 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));
0 голосов
/ 15 октября 2018

Ваша проблема в том, что вы перезаписываете данные, не сохраняя их

$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 Object.Поэтому нет необходимости хранить все эти объекты в памяти, а код намного меньше, чище и проще для чтения.

Последнее, на что я намекал в коде, это то, что объекты передаются по ссылке.в 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 loop, это тот же массив, с каждой строкой, добавляемой после каждой итерации.

Как видите, каждая копия (на самом деле это не копия) обновляется по ссылке в массиве.В основном мы сохранили один и тот же объект (экземпляр будет называть его Bob) 3 раза вместо 3 отдельных объектов (Bob, Alice, John).

Если данные, которые вы сохранилибыл цвета рубашки людей, когда Bob надевает красную рубашку, на нем красная рубашка, но Alice и John нет.

Из-за этого вам нужно создавать новый экземпляр объекта для каждой итерации и сохранять его.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...