从MySQL查询构建数组以格式化json

时间:2014-11-20 23:55:12

标签: php mysql arrays json multidimensional-array

我从mysql结果中为预期的json格式构建正确的数组是个问题:

表:

    CREATE TABLE `Config_Category` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(50) NOT NULL DEFAULT '0',
    `topid` INT(8) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`)
    )
    ;

填表:

id  name        topid
2   DVD         1
3   Matrix      2
4   CD          1
5   Deep Purple 4
6   Pink Floyd  4
7   Batman      2
MyClass
{
    public function getMenu($topid)
    {

        $stmt = $this->pdoDash->query("SELECT id,name 
            FROM Config_Category WHERE topid='$topid'");

        $results = $stmt->fetchAll(PDO::FETCH_ASSOC);

        foreach ($results as $row)
        {
            if ($this->hasChildKats($row['id']))
            {
                $path[] = array("group" => $row['name']);
                $path[] = array_merge($this->getMenu($row['id'], $path));

            } else
            {
                $path["item"][] = array("name" => $row['name']);

            }
        }
        return $path;
    }

    private function hasChildKats($katID)
    {
        $stmt = $this->pdoDash->query("SELECT count(*) 
            FROM Config_Category WHERE topid='$katID'");

        return $stmt->fetchColumn();
    }
}

$this->test = new MyClass;
echo json_encode($this->test->getMenu());

我的结果:

[
{
    "group": "DVD"
},
{
    "item": [
        {
            "name": "Matrix"
        },
        {
            "name": "Batman"
        }
    ]
},
{
    "group": "CD"
},
{
    "item": [
        {
            "name": "Pink Floyd"
        },
        {
            "name": "Deep Purple"
        }
    ]
}
]

预期结果:

[
{
    "group": "DVD",
    "item": [
        {
            "name": "Matrix"
        },
        {
            "name": "Batman"
        }
    ]
},
{
    "group": "CD",
    "item": [
        {
            "name": "Pink Floyd"
        },
        {
            "name": "Deep Purple"
        }
    ]
}
]

2 个答案:

答案 0 :(得分:0)

在我看来,使用空括号[]是导致此行为的原因。您应该尝试使用变量作为计数器:

var $counter = 0;

foreach ($results as $row)
{
    if ($this->hasChildKats($row['id']))
    {
        $path[$counter] = array("group" => $row['name']);
        $path[$counter] = array_merge($this->getMenu($row['id'], $path));

    } else
    {
        $path["item"][$counter] = array("name" => $row['name']);
    }
    $counter++;
}

答案 1 :(得分:0)

我经常遇到这样的数据库访问模式。我通常可以加速100倍或更多。您似乎在打印的菜单中每行至少敲击一次数据库。然而,这可以在单个DB调用和PHP循环中解决。

以下是一个如何运作的例子。 (可能与您的数据模型不完全匹配)。 注意:我总是以复数形式命名项目数组,所以我改变了项目'到'项目'故意

public function getMenu($topid) {

    $stmt = $this->pdoDash->query("SELECT id, name, topid FROM Config_Category");
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);

    $path = array();
    foreach ($results as $row) {
        if ($row['topid'] == 1) {   // top level category
            $path[$row['id']] = array();
            $path[$row['id']]['group'] = row['name'];
        } else {    // child category
            $path[$row['topid']]['items'][] = array('name'=>row['name']);
        }
    }
    return $path;
}