簡體   English   中英

如何將 JSON 數據導入 MySQL 就像 CSV show's it

[英]How can I import JSON data into MySQL just like CSV show's it

在導出數據期間,我可以在 CSV 和 JSON 格式之間進行選擇。 查看 CSV,數據(包括列名)的排列方式與我想導入 MySQL 數據庫的方式完全相同。

CSV 截圖

我從網頁獲取 JSON,它存儲在 $data 變量中。

<html>
    <body>
        <?php

          // Include Parsehub REST api wrapper 
          require_once __DIR__ . '/vendor/autoload.php';
          use Parsehub\Parsehub;
          $api_key = "XXX";
          $project_token = "XXX";
          

          $parsehub = new Parsehub($api_key);
          $data =  $parsehub->getLastReadyRunData($project_token);
          echo $data;

        ?>

    </body>
</html>


Echo output 會返回 JSON: https://pastebin.com/raw/AZt4gvsC

創建表:

CREATE TABLE `utakmice_1` (
  `utakmica_name` varchar(64) NOT NULL,
  `utakmica_url` varchar(256) NOT NULL,
  `utakmica_liga` varchar(64) NOT NULL,
  `utakmica_liga_url` varchar(256) NOT NULL,
  `utakmica_vreme` varchar(64) NOT NULL,
  `utakmica_datum` varchar(64) NOT NULL,
  `utakmica_kvote_kvota` decimal(10,2) NOT NULL,
  `utakmica_kvote_kladionica` varchar(63) NOT NULL,
  `utakmica_kvote_kladionica_url` varchar(256) NOT NULL,
  `utakmica_kvote_igra` varchar(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

json的數據怎么插入?

使用PHP,您需要:

使用json_decode將 JSON 數據轉換為關聯數組

$data = json_decode($jsondata, true);

處理該數組以獲取您需要插入表中的數據

$name = $data['utakmica']['name'];
$url = $data['utakmica']['age'];
etc

使用插入查詢插入到 MySQL(我們在這里使用mysqli但您可以使用PDO

$sql = "INSERT INTO utakmice_1(utakmica_name, utakmica_url)
    VALUES('$name', '$url')";
if(!mysqli_query($con, $sql))
{
    die('Error : ' . mysql_error());
}

給定 CSV 顯示和 JSON 中的結構,當對 JSON 結構進行標准遞歸迭代並修改終止葉子是不再包含數組屬性的對象時,有可能遍歷所有具有它們的屬性名稱以所有父屬性名稱為前綴(刪除數組索引)並按深度升序使用所有較低深度的當前對象(來自子迭代器)來創建合並的 object 以獲得具有此類鍵的此類對象。

這個樣板是RecursiveArrayIteratorRecursiveIteratorIterator

重要的是,如果 object 有一個屬性是數組,那么它是唯一一個數組屬性,數組是一個對象數組,所有對象都是同構的。 您的 JSON 文本就是這種情況,這很重要,因為RecursiveArrayIteratorRecursiveIteratorIterator都需要為此類遍歷進行修改。

未修改的樣板行為也顯示在相關的問答中如何使用 PHP 解析 JSON 文件? :

$it = new RecursiveIteratorIterator(
    new RecursiveArrayIterator($json)
);
foreach ($it as $property => $value) {
   ...
}

因為在您的用例中,兩個對象都需要修改,並且它只適用於僅留下迭代(因為只有合並對象才有意義),整個構造可以從RecursiveIteratorIterator擴展,直接使用$json覆蓋構造函數,使用RecursiveArrayIterator的修改。

說到這里,它需要保留鍵前綴(這里作為私有屬性實現),將對象變成不可遍歷的子對象(標准行為是每個非對象和非數組屬性構成一個葉子)並移除數組屬性從每個節點開始,因為那些應該只能遍歷到葉節點,然后當按深度升序合並整個路徑時,它們將是多余的:

$it = new class ($json) extends \RecursiveIteratorIterator {
    public function __construct(object $json)
    {
        $jsonObjectRecursion = new class($json) extends \RecursiveArrayIterator
        {
            private ?string $keyPrefix = null;

            public function key()
            {
                return (null !== $this->keyPrefix ? $this->keyPrefix . '_' : '') . parent::key();
            }

            public function current(): object|array
            {
                $current = parent::current();
                if (is_array($current)) {
                    return $current;
                }

                $current = array_filter(get_object_vars($current), static fn ($any) => !is_array($any));
                if (null !== $this->keyPrefix) {
                    $current = array_combine(preg_filter('/^/', "{$this->keyPrefix}_", array_keys($current)), $current);
                }
                return (object)$current;
            }

            public function hasChildren(): bool
            {
                $current = parent::current();
                if (is_array($current)) {
                    return parent::hasChildren();
                }
                return (is_object($current) && array_filter(get_object_vars($current), 'is_array'));
            }

            public function getChildren(): self
            {
                $current = parent::current();
                if (is_array($current)) {
                    $children = parent::getChildren();
                    $children->keyPrefix = $this->key();
                    return $children;
                }

                $probe = array_filter(get_object_vars($current), 'is_array');
                $children = new self((object) [key($probe) => current($probe)]);
                $children->keyPrefix = $this->keyPrefix;
                return $children;
            }
        };

        parent::__construct($jsonObjectRecursion);
    }
    ...

正如這段摘錄所示,數組遍歷被保留並且鍵前綴被相應地傳遞。 current()中的數組處理可能會被刪除,因為 arrays 僅在has / getChildren()調用中起作用。

$json就是這個大的 JSON Object 解碼為 PHP 的 stdClass。 RecursiveArrayIterator盡管它的名稱中有Array ,但無需將它們轉換為數組即可很好地處理這些 JSON 對象。

在僅定義內部迭代器的構造函數旁邊,此RecursiveIteratorITerator僅實現第二個方法current() ,該方法進行合並:

    ...

    public function current(): object
    {
        $object = [];
        for ($depth = 0; $depth <= $this->getDepth(); $depth++) {
            $current = $this->getSubIterator($depth)->current();
            if (is_array($current)) {
                continue;
            }
            $object += get_object_vars($current);
        }
        return (object)$object;
    }
};

正如$it現在定義的那樣,所有需要的是迭代它並繼續處理值:

foreach ($it as $row) {
    echo json_encode($row, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), "\n";
    break;
}

Output(第一平排):

{
    "utakmica_name": "Deportivo Kuenka-Un. Katolika Kito",
    "utakmica_url": "https://www.fudbal91.com/soccer_clubs/compare/Deportivo_Cuenca_vs_Un._Catolica_Quito/13641",
    "utakmica_liga": "Ekvador 1",
    "utakmica_liga_url": "https://www.fudbal91.com/competition/Ecuador,_LigaPro_betcris_-_Primera_Etapa/2022",
    "utakmica_vreme": "00:00",
    "utakmica_datum": "< 22.03.2022. (Utorak) >",
    "utakmica_kvote_kvota": "2.75",
    "utakmica_kvote_kladionica": "BetOle",
    "utakmica_kvote_kladionica_url": "https://example.com/2YjM4Ft",
    "utakmica_kvote_igra": "1"
}

要將$it轉換為對象數組,請使用iterator_to_array($it, false) 例如,當您希望通過一個屬性對整個列表進行排序,而無需每次操作都一次又一次地遍歷整個樹時。

就像您會使用已經平坦的 CSV 導出一樣。

這些甚至更多的技巧可以在相關的問答中找到如何使用 PHP 從 JSON 中提取和訪問數據? 以及網站上的更多其他人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM