【问题标题】:Parse through a nested array and save it in mysql db with parent id解析嵌套数组并将其保存在具有父 ID 的 mysql db 中
【发布时间】:2018-06-21 09:14:56
【问题描述】:

我有一个嵌套数组,如下所示:-

array(
    array(
        'id' => 45cfeteuid536hjj929,
        'name' = 'Cuisines',
        'children' => array(
            array(
                'id' => 45gcfeteuid536hjj929,
                'name' = 'Itlaian',  
            ),
            array(
                'id' => 45bjfe78ng5d536hjj92,
                'name' = 'Indian',
                'children' => array(
                    array(
                        'id' => 457hfe78ng5d53ghy56j,
                        'name' = 'Punjabi'
                    )
                )
            )
        )
    )
);

我有一张这样的桌子:-

|--------------------------------|
|   id  |   name   |  parent_id  |
|--------------------------------|

我希望像这样插入数据:-

|---------------------------------------------------------------|
|   id  |   name     |  parent_id  |    api_id                  |
|---------------------------------------------------------------|
|    1  |   Cuisines |      0      |    45cfeteuid536hjj929     |
|---------------------------------------------------------------|
|    2  |   Italian  |      1      |    45gcfeteuid536hjj929    |
|---------------------------------------------------------------|
|    3  |    Indian  |      1      |    45bjfe78ng5d536hjj92    |
|---------------------------------------------------------------|
|    4  |   Punjabi  |      3      |    457hfe78ng5d53ghy56j    |
|---------------------------------------------------------------|

child 的 parent_id 是它所属的对象的 id。表的id是mysql db自动生成的自增值。

例如:-

  • 第 1 步:在保存美食时,保存了 id(本质上是自动增量) 是1。因为它是根,所以parent_id = 0。
  • 第 2 步:在保存意大利语时,id(本质上是自动增量) 保存为 1。由于是 Cuisines 的子项,因此 parent_id = 1

如何以这种方式保存嵌套数组?

【问题讨论】:

  • 请分享你的尝试?
  • 我不确定:parent_id 是同一表中其他行的 id id
  • @MickaelLeger,更新了文档
  • 好的,所以 parent_id 对于每个 root parent 都将为 0,并且孩子应该将父母的 id 视为 parent_id。我不知道这样做是否是一个好习惯(如果删除父级会发生什么,你需要删除所有子级?),但一种方法可能是使用递归函数,也许你存储最后一个 @ 987654330@ 之后再用吗?你在使用 PDO 吗?
  • 没有。我正在使用 Laravel Eloquent。

标签: php multidimensional-array laravel-5.6


【解决方案1】:

一种方法是生成如下所示的insert 语句(假设您的表名为tab):

insert into tab(name, parent_id, app_id) 
    select 'Cuisines', coalesce(min(id), 0), '45cfeteuid536hjj929' from tab
    where app_id = '';
insert into tab(name, parent_id, app_id)
    select 'Itlaian', coalesce(min(id), 0), '45gcfeteuid536hjj929' from tab
    where app_id = '45cfeteuid536hjj929';
insert into tab(name, parent_id, app_id)
    select 'Indian', coalesce(min(id), 0), '45bjfe78ng5d536hjj92' from tab
    where app_id = '45cfeteuid536hjj929';
insert into tab(name, parent_id, app_id)
    select 'Punjabi', coalesce(min(id), 0), '457hfe78ng5d53ghy56j' from tab
    where app_id = '45bjfe78ng5d536hjj92';

这些查询将通过父级应具有的app_id 找到父级 ID。没有插入id 列的值,因为假定数据库将在插入时生成它。

这是一个生成这些语句的递归 PHP 函数。您必须调整它以使用您使用的任何 API(PDO、mysqli、...)实际执行这些语句:

function insertRecords($data, $parent = "") {
    foreach($data as $row) {
        // Replace next echo statement with the code to actually execute this SQL:
        echo "insert into tab(name, parent_id, app_id) select '$row[name]', coalesce(min(id), 0), '$row[id]' from tab where app_id = '$parent';\n";
        if (isset($row["children"])) insertRecords($row["children"], $row["id"]);
    }
}    

假设你的嵌套数据结构存储在变量$data中,像这样调用上面的函数:

insertRecords($data);

【讨论】:

  • 很好的答案,但我认为在一次调用后递归函数会忘记主嵌套数组。我的意思是它会运行一个完整的级别,但不是全部,如果我错了,请纠正我。
  • 只要有子属性,它就会继续深入。
  • @ShashikumarMisal,为什么认为它会忘记$data$row 都是函数执行上下文的局部变量。他们不会被遗忘。
猜你喜欢
  • 2019-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-04
  • 2021-07-23
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
相关资源
最近更新 更多