需要帮助使用PHP将关联数组转换为嵌套JSON

时间:2016-07-03 10:07:32

标签: php mysql json

过去一周我一直在努力解决这个问题,这让我很生气,所以如果有人能帮助我,我会永远感激。

查询我的数据库后,我用以下内容迭代数据:

while ($row=mysqli_fetch_assoc($result)) {...

这是行的构造方式:

示例第1行:

(
"countryId" => "2",
"countryDescription" => "Canada",
"cityId" => "3",
"cityDescription" => "Montreal",
"restaurantFranchiseId" => "2",
"restaurantFranchiseDescription" => "Kentucky Fried Chicken"
)

示例第2行:

(
"countryId" => "2",
"countryDescription" => "Canada",
"cityId" => "3",
"cityDescription" => "Montreal",
"restaurantFranchiseId" => "3",
"restaurantFranchiseDescription" => "Taco Bell"
)

请注意,只有餐厅特许经营权在上面两行中有所不同。两个国家和城市都是相同的。

我想将行转换为嵌套的JSON文件,如下所示。如下所示,每个国家/地区都是一个独特的对象。每个城市都是一个独特的对象,也是其对应国家/地区对象的子元素。然而,餐厅特许经营并非独一无二,因为它们与特定国家或城市无关。

如何从我的数据创建下面的JSON文件,其结构如上所述?

感谢!!!

{
"Countries": [{
    "countryId": "1",
    "countryDescription": "USA",
    "cities": [{
        "cityId": "1",
        "cityDescription": "Houston",
        "restaurantFranchises": [{
            "restaurantFranchiseId": "1",
            "restaurantFranchiseDescription": "Mc Donald's"
        }, {
            "restaurantFranchiseId": "2",
            "restaurantFranchiseDescription": "Kentucky Fried Chicken"
        }, {
            "restaurantFranchiseId": "4",
            "restaurantFranchiseDescription": "Pizza Hut"
        }]
    }, {
        "cityId": "2",
        "cityDescription": "New york",
        "restaurantFranchises": [{
            "restaurantFranchiseId": "1",
            "restaurantFranchiseDescription": "Mc Donald's"
        }, {
            "restaurantFranchiseId": "4",
            "restaurantFranchiseDescription": "Pizza Hut"
        }]
    }]
}, {
    "countryId": "2",
    "countryDescription": "Canada",
    "cities": [{
        "cityId": "3",
        "cityDescription": "Montreal",
        "restaurantFranchises": [{
            "restaurantFranchiseId": "1",
            "restaurantFranchiseDescription": "Mc Donald's"
        }, {
            "restaurantFranchiseId": "3",
            "restaurantFranchiseDescription": "Taco Bell"
        }, {
            "restaurantFranchiseId": "4",
            "restaurantFranchiseDescription": "Pizza Hut"
        }]
    }, {
        "cityId": "4",
        "cityDescription": "Ottawa",
        "restaurantFranchises": [{
            "restaurantFranchiseId": "2",
            "restaurantFranchiseDescription": "Kentucky Fried Chicken"
        }, {
            "restaurantFranchiseId": "3",
            "restaurantFranchiseDescription": "Taco Bell"
        }, {
            "restaurantFranchiseId": "4",
            "restaurantFranchiseDescription": "Pizza Hut"
        }]
    }]
}]

}

1 个答案:

答案 0 :(得分:1)

您可以使用此代码:

$result = [];
$lastCity = [ "cityId" => null ];
$lastCountry = [ "countryId" => null ];
while ($row=mysqli_fetch_assoc($result)) {
    if ($row["countryId"] !== $lastCountry["countryId"]) {
        // Country is not the same as in previous row, so create
        // a new entry for it in the first level of the result array. 
        // The city and franchises data will be inserted further down.
        $result[] = [
            "countryId" => $row["countryId"],
            "countryDescription" => $row["countryDescription"],
            "cities" => []
        ];
        // Get a reference (`&`) to the new country entry added to `$result`.
        // Whatever is later changed in `$lastCountry` will change inside the
        // `$result` data structure.
        $lastCountry = &$result[count($result)-1];
    }
    if ($row["cityId"] !== $lastCity["cityId"]) {
        // City is not the same as in previous row, so create
        // a new entry for it in the second level of `$result`.
        // We use the `$lastCountry` "shortcut" to manipulate `$result`.
        $lastCountry["cities"][] = [
            "cityId" => $row["cityId"],
            "cityDescription" => $row["cityDescription"],
            "restaurantFranchises" => []
        ];
        // Get a reference (`&`) to the new city entry added to `$result`.
        // Whatever is later changed in `$lastCity` will change inside the
        // `$result` data structure (and `$lastCountry`).
        $lastCity = &$lastCountry["cities"][count($lastCountry["cities"])-1];
    }
    // Create a new entry for the franchise in the third level of `$result`.
    // We use the `$lastCity` "shortcut" to manipulate `$result`.
    $lastCity["restaurantFranchises"][] = [
        "restaurantFranchiseId" => $row["restaurantFranchiseId"],
        "restaurantFranchiseDescription" => $row["restaurantFranchiseDescription"],
    ];
}

eval.in上看到它。

关于辅助变量

两个变量$lastCity$lastCountry是对$result数据结构中位置的引用(除了在循环开始时它们是虚拟值)。要在$result数组中获取此类引用,请使用& operator。它可以在没有这两个变量的情况下完成,但它会使赋值语句很长,因为每次$result数组中的最后一个元素都需要引用它,从该元素中获取其cities中的最后一个元素1}}数组,...等。

假设

此算法需要按国家和城市排序您的查询结果集,即一个城市不应该首先是“纽约”,然后是“洛杉矶”,然后是“纽约”。

此外,假设 cityId 值是唯一的。例如,美国的某个城市不应该与加拿大的城市具有相同的 cityId 。如果是这种情况,则应略微调整上述代码。