PHP json_decode из API в sql: импортирует только объекты, не содержащие пустых значений - PullRequest
0 голосов
/ 16 июня 2020

Хотя есть много похожих тем, go они не относятся к проблеме, которая у меня возникает, поэтому хотелось бы получить небольшое разъяснение.

Я создаю базу данных с некоторыми данными из различные API, данные, поступающие из этих API, имеют формат JSON (некоторые из них являются объектами, некоторые - массивами).

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

/*CONECT TO DB - TESTING ON LOCAL MACHINE*/ 
$connect = mysqli_connect("localhost", "root", "", "test"); //Connect PHP to MySQL Database
$query = '';

/*CLEAR/TRUNCATE TABLE TO REFRESH ALL CONTENTS FROM API*/
$ins_qry = "TRUNCATE TABLE Derivatives";
mysqli_query($connect,$ins_qry);

$url = "https://api.xxxxxxxx";
$content = file_get_contents($url);
$jsonData = json_decode($content, true);

foreach ( $jsonData as $id=>$row ) {
    $insertPairs = array();
    foreach ($row as $key=>$val) {
      $insertPairs[addslashes($key)] = addslashes($val);
    }
    $insertKeys = '`' . implode('`,`', array_keys($insertPairs)) . '`';
    $insertVals = '"' . implode('","', array_values($insertPairs)) . '"';   

    /*JUST FOR CHECKING RESULTS ON PAGE*/
    echo "INSERT INTO Derivatives ({$insertKeys}) VALUES ({$insertVals});" . "\n";

/*THE QUERY*/
$query = "INSERT INTO Derivatives ({$insertKeys}) VALUES ({$insertVals});" . "\n";
if (mysqli_multi_query($connect, $query)) ;

}

mysqli_close($connect);

Данные JSON выглядят следующим образом:

[
 {
    "market": "OKEx (Futures)",
    "symbol": "BTC-USD-SWAP",
    "coin_id": "bitcoin",
    "index_id": "OkexSwap-BTC",
    "price": "9520.5",
    "price_percentage_change_24h": 4.801690829232852,
    "contract_type": "perpetual",
    "index": 9526.418,
    "basis": 0.06216060080878105,
    "spread": null,
    "funding_rate": 0.011057,
    "open_interest": 116495100,
    "volume_24h": 466882900,
    "last_traded_at": 1592306177,
    "expired_at": null
  },
.
.
.
]

Обратите внимание, что некоторые значения null из случайных мест, например, в объекте выше "spread" и "expired_at" равны null, на следующих объектах могут быть другие, а на некоторых других все значения присутствуют.

В ECHO из моего кода и следуя приведенному выше примеру я получаю что-то вроде этого:

INSERT INTO Derivatives 
    (`market`,`symbol`,`coin_id`,`index_id`,`price`,
    `price_percentage_change_24h`,`contract_type`,
    `index`,`basis`,`spread`,`funding_rate`,
    `open_interest`,`volume_24h`,`last_traded_at`,
    `expired_at`) 
VALUES ("OKEx (Futures)","BTC-USD-SWAP","bitcoin","OkexSwap-BTC","9504.2",
    "0.86279170955863","perpetual","9506.228","0.021337934807759",
    "","-0.004262","111364600","411804300","1592331559","");

(Не беспокойтесь о некоторых изменениях значений, поскольку они загружаются в разное время, это просто пример)

Обратите внимание, что значения, которые w Теперь null преобразуется в "".

Что происходит при проверке таблицы в самой БД, так это то, что из ожидаемых около 500 объектов у меня есть только 60, те 60 - те, которые завершены на JSON файла, у них нет NULL.

Каждый объект, имеющий значение NULL, не попадает в БД.

Я попытался написать код, который возвращает «NULL» вместо « "в операторе запроса, но если я попробую это на phpmyadim просто для проверки, это даст мне ошибки, поскольку отсутствующие поля, о которых идет речь, являются либо плавающими, либо временными метками, а БД не принимает строку" Null "или пустую" ".

Таблица создана для приема NULL в этих полях, проблема в том, что PHP отправляет запрос с «», поэтому я не могу отправить все объекты.

Есть идеи? Спасибо

(я знаю, что могу импортировать как JSON, но мне действительно нужна обычная таблица со всеми строками)

1 Ответ

0 голосов
/ 16 июня 2020

Например;

<?php
$arr = ['a', '', null];

$values = join(', ', array_map(function ($value) {
    return $value === null ? 'NULL' : "'$value'";
}, $arr));

var_dump($values); // string(13) "'a', '', NULL"

Обновление:

addslashes также преобразует значения NULL в пустые строки

Обратите внимание, что SQL инъекция возможна! Используйте вместо этого подготовленные операторы!

<?php

$json = '[{
    "market": "OKEx (Futures)",
    "symbol": "BTC-USD-SWAP",
    "coin_id": "bitcoin",
    "index_id": "OkexSwap-BTC",
    "price": "9520.5",
    "price_percentage_change_24h": 4.801690829232852,
    "contract_type": "perpetual",
    "index": 9526.418,
    "basis": 0.06216060080878105,
    "spread": null,
    "funding_rate": 0.011057,
    "open_interest": 116495100,
    "volume_24h": 466882900,
    "last_traded_at": 1592306177,
    "expired_at": null
}]';

$jsonData = json_decode($json, true);

foreach ($jsonData as $id => $row) {

    $insertKeys = join(', ', array_map(function ($value) {
        return $value === null ? 'NULL' : "`".addslashes($value)."`";
    }, array_keys($row)));

    $insertVals = join(', ', array_map(function ($value) {
        return $value === null ? 'NULL' : "'".addslashes($value)."'";
    }, array_values($row)));


    echo "INSERT INTO Derivatives ({$insertKeys}) VALUES ({$insertVals});" . "\n";

    /* 
    INSERT INTO Derivatives 
        (`market`, `symbol`, `coin_id`, `index_id`, `price`, `price_percentage_change_24h`, `contract_type`, `index`, `basis`, `spread`, `funding_rate`, `open_interest`, `volume_24h`, `last_traded_at`, `expired_at`) 
    VALUES 
        ('OKEx (Futures)', 'BTC-USD-SWAP', 'bitcoin', 'OkexSwap-BTC', '9520.5', '4.8016908292329', 'perpetual', '9526.418', '0.062160600808781', NULL, '0.011057', '116495100', '466882900', '1592306177', NULL);
    */
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...