Json кодировать в неправильном формате - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь собрать статистику посещений моего сайта.Я знаю, что могу использовать Google Analytics (что я и делаю), но я хочу попробовать что-то сделать сам, и это хороший способ научиться этому.

Проблема: Я выбираю датыв моей базе данных и сортировать их, чтобы соответствовать этой неделе.После этого я хочу добавить их в файл JSON.Этот файл json используется CanvasJS для создания диаграммы.Я пробовал несколько разных способов, просто чтобы заставить его работать.Но формат массива json не тот, который хочет CanvasJS.

Что мне нужно:

{ visits:[[2019-02-12, 49,],[2019-02-13,40,],[2019-02-14,46,],[2019-02-15,37,], [2019-02-16,31,],[2019-02-17,38,],[2019-02-18,4,] }

Что я получаю:

{ "visits":{"2019-02-12":49,"2019-02-13":40,"2019-02-14":46,"2019-02-15":37,"2019-02-16":31,"2019-02-17":38,"2019-02-18":4} }

Мой сценарий PHP:

// Get first and last day of the current week
$first_day = date('Y-m-d', strtotime("- 6 days"));
$last_day = date('Y-m-d', strtotime("+ 1 days "));

// Return all results the past 7 days
$sql = "SELECT date FROM table WHERE date >= '" . $first_day . "' AND date < '" . $last_day . "'";
if($result = $conn->query($sql)){

    $response = array(); 
    $visits = array();

    while($row = $result->fetch_array(MYSQLI_ASSOC)){

        $old_date = $row['date'];
        $old_date_timestamp = strtotime($old_date);
        $new_date = date('Y-m-d', $old_date_timestamp);

                // I dont need the keys, but I cant avoid it to
                // get it to work....
        $visits[] = array(
            'date' => $new_date
        );

    }

    // Add sum of Dates
    $response['visits'] = array_count_values(array_column($visits, 'date'));

    // Save to json File
    $fp = fopen('results.json', 'w');
    fwrite($fp, json_encode($response));
    fclose($fp);
}
$conn->close();

Спасибо всем, кто сможет помочь.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Насколько я понимаю, вы хотите сгруппировать ту же дату, что и массив, в посещениях, если я правильно понимаю, что здесь есть решение.

Добавьте еще один цикл для создания массива php перед тем, как изменить его на строку json.

$first_day = date('Y-m-d', strtotime('- 6 days'));
$last_day = date('Y-m-d', strtotime('+ 1 days '));

$sql = "SELECT date FROM table WHERE date >= '" . $first_day . "' AND date < '" . $last_day . "'";
if ($result = $conn->query($sql)) {
    $response = [];
    $visits = [];

    while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
        $old_date = $row['date'];
        $old_date_timestamp = strtotime($old_date);
        $new_date = date('Y-m-d', $old_date_timestamp);

        $visits[] = [
        'date' => $new_date
    ];
    }

    // here the change start
    $format = [];
    foreach ($visits as $visit) {
        $format[$visit['date']][] = $visit['date'];
    }
    $response['visits'] = array_values($format);
    // here the change end

    $fp = fopen('results.json', 'w');
    fwrite($fp, json_encode($response));
    fclose($fp);
}
$conn->close();

если вам не нужен ключ date здесь другое решение

$first_day = date('Y-m-d', strtotime('- 6 days'));
$last_day = date('Y-m-d', strtotime('+ 1 days '));

$sql = "SELECT date FROM table WHERE date >= '" . $first_day . "' AND date < '" . $last_day . "'";
if ($result = $conn->query($sql)) {
    $response = [];
    $visits = [];

    while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
        $old_date = $row['date'];
        $old_date_timestamp = strtotime($old_date);
        $new_date = date('Y-m-d', $old_date_timestamp);

        $visits[$new_date][] = $new_date; // change here
    }

    $response['visits'] = array_values($visits); // change here

    $fp = fopen('results.json', 'w');
    fwrite($fp, json_encode($response));
    fclose($fp);
}
$conn->close();

Пояснение

в PHP существует два типа индексированных массивов и ассоциативный, когда вы меняете массив PHP на строку json, индексированный массив становится массивом, а ассоциативный - объектом.

пример

$indexed = [
    0 => 'foo',
    1 => 'bar'
];

$associative = [
    'one' => 'foo',
    'two' => 'bar'
];

var_dump(json_encode($indexed));
// [
//   "foo",
//   "bar"
// ]

var_dump(json_encode($associative));
// {
//   one: "foo",
//   two: "bar"
// }

в моем коде, который я используюдата посещения в качестве ключа, таким образом, та же дата будет помещена в тот же массив, и я array_values для преобразования ассоциативных в индексированные

0 голосов
/ 18 февраля 2019

Игнорирование любых связанных с кавычками проблем, которые вы можете считать проблемами (но не проблемами), похоже, ваше основное различие заключается в том, что вы хотите ...

[[2019-02-12, 49,],...

и тем, что у вас есть ...

{"2019-02-12":49,...

Это потому, что array_count_values() создает ассоциативный массив с вашими датами в качестве ключей.

Ваша проблема может быть значительно упрощена, если вы получитебазу данных группировать и считать вместо того, чтобы делать это в PHP.Вы также можете извлечь выгоду из использования подготовленного оператора вместо прямого введения значения.

// Get first and last day of the current week
$first_day = date('Y-m-d', strtotime("- 6 days"));
$last_day = date('Y-m-d', strtotime("+ 1 days "));

$sql = <<<_SQL
SELECT DATE(`date`), COUNT(1)
FROM `table` WHERE `date` BETWEEN ? AND ?
GROUP BY DATE(`date`)
_SQL;

$stmt = $conn->prepare($sql);
$stmt->bind_param('ss', $first_day, $last_day);
$stmt->execute();
$stmt->bind_result($date, $count);
while ($stmt->fetch()) {
    $visits[] = [$date, $count];
}
$response = [ 'visits' => $visits ];

// Save to json File
$fp = fopen('results.json', 'w');
fwrite($fp, json_encode($response));
fclose($fp);
...