1

我有 2 个数据库表。表 2 与表 1 相关。

在 php 中,我正在构建一个多维数组来保存数据键/值。

因为 PHP 需要具有唯一的“键”,所以我的 JSON 看起来像这样:

[
{
    "packs": {
        "9": {
            "characters": {
                "40": {
                    "id": "40",
                    "title": "Jack Bauer",
                    "pic": "68bcbe014c.jpg",
                    "gender": "Male"
                },
                "41": {
                    "id": "41",
                    "title": "Chloe O'Brian",
                    "pic": "ffb6acc8e3.jpg",
                    "gender": "Male"
                },
                "42": {
                    "id": "42",
                    "title": "Tony Almeida",
                    "pic": "23f199e223.jpg",
                    "gender": "Male"
                }
            }
        },
        "7": {
            "characters": {
                "7": {
                    "id": "7",
                    "title": "Elvis Presley",
                    "pic": "78300767ad.jpg",
                    "gender": "Male"
                },
                "16": {
                    "id": "16",
                    "title": "Madonna",
                    "pic": "70663a42f7.jpg",
                    "gender": "Male"
                },
                "17": {
                    "id": "17",
                    "title": "Lady Gaga",
                    "pic": "c5099c619b.jpg",
                    "gender": "Male"
                },
                "21": {
                    "id": "21",
                    "title": "Pink Floyd",
                    "pic": "52ddce314a.jpg",
                    "gender": "Male"
                },
                "22": {
                    "id": "22",
                    "title": "Led Zeppelin",
                    "pic": "84cd58ada3.jpg",
                    "gender": "Male"
                },
                "31": {
                    "id": "31",
                    "title": "The Beatles",
                    "pic": "bd22a4d648.jpg",
                    "gender": "Male"
                },
                "32": {
                    "id": "32",
                    "title": "Foo Fighters",
                    "pic": "250fb6ecec.jpg",
                    "gender": "Male"
                },
                "33": {
                    "id": "33",
                    "title": "Bananarama",
                    "pic": "da7c2b56cf.jpg",
                    "gender": "Male"
                },
                "35": {
                    "id": "35",
                    "title": "Boney-M",
                    "pic": "3cbdada38b.jpg",
                    "gender": "Male"
                },
                "38": {
                    "id": "38",
                    "title": "The Spice Girls",
                    "pic": "4751f0fbb7.jpeg",
                    "gender": "Male"
                },
                "39": {
                    "id": "39",
                    "title": "Girls Aloud",
                    "pic": "644dcf71ca.jpg",
                    "gender": "Male"
                }
            }
        },
        "8": {
            "characters": {
                "9": {
                    "id": "9",
                    "title": "Keith Lemon",
                    "pic": "ff6ef10853.jpg.jpg",
                    "gender": "Male"
                },
                "23": {
                    "id": "23",
                    "title": "Fearne Cotton",
                    "pic": "0d038b6516.jpg",
                    "gender": "Male"
                },
                "24": {
                    "id": "24",
                    "title": "Holly Willoughby",
                    "pic": "836fc4184c.jpg",
                    "gender": "Male"
                },
                "30": {
                    "id": "30",
                    "title": "Rufus Hound",
                    "pic": "062bee9602.jpg",
                    "gender": "Male"
                }
            }
        },
        "3": {
            "characters": {
                "5": {
                    "id": "5",
                    "title": "Tom Cruise",
                    "pic": "ff296fafb9.jpg",
                    "gender": "Male"
                },
                "10": {
                    "id": "10",
                    "title": "Linda Lovelace",
                    "pic": "ac1bea43d3.jpg",
                    "gender": "Male"
                },
                "15": {
                    "id": "15",
                    "title": "Gwyneth Paltrow",
                    "pic": "43a22d7240.jpg",
                    "gender": "Male"
                },
                "44": {
                    "id": "44",
                    "title": "Errol Flynn",
                    "pic": "cea17c1275.jpg",
                    "gender": "Male"
                },
                "45": {
                    "id": "45",
                    "title": "Halle Berry",
                    "pic": "752b5c92c5.jpg",
                    "gender": "Male"
                }
            }
        },
        "2": {
            "characters": {
                "4": {
                    "id": "4",
                    "title": "Donald Duck",
                    "pic": "8d367f41b1.jpg",
                    "gender": "Male"
                },
                "6": {
                    "id": "6",
                    "title": "Mickey Mouse",
                    "pic": "8d9629c115.jpg",
                    "gender": "Male"
                },
                "28": {
                    "id": "28",
                    "title": "Pluto",
                    "pic": "fb2c0e2dd0.jpg",
                    "gender": "Male"
                },
                "29": {
                    "id": "29",
                    "title": "Minnie Mouse",
                    "pic": "378760ff77.jpg",
                    "gender": "Male"
                },
                "36": {
                    "id": "36",
                    "title": "Cinderella",
                    "pic": "a7e4888213.jpg",
                    "gender": "Male"
                },
                "37": {
                    "id": "37",
                    "title": "Snow White",
                    "pic": "a9cf05a857.jpg",
                    "gender": "Male"
                }
            }
        },
        "4": {
            "characters": {
                "3": {
                    "id": "3",
                    "title": "Bill Clinton",
                    "pic": "03c6567ddb.jpg",
                    "gender": "Male"
                },
                "11": {
                    "id": "11",
                    "title": "Margaret Thatcher",
                    "pic": "91c9fa9fd0.jpg",
                    "gender": "Male"
                },
                "13": {
                    "id": "13",
                    "title": "David Cameron",
                    "pic": "a689984360.jpg",
                    "gender": "Male"
                },
                "14": {
                    "id": "14",
                    "title": "Nick Clegg",
                    "pic": "3243e298e5.jpg",
                    "gender": "Male"
                },
                "26": {
                    "id": "26",
                    "title": "George Bush JR",
                    "pic": "46296f6b0e.jpg",
                    "gender": "Male"
                },
                "27": {
                    "id": "27",
                    "title": "Ed Milliband",
                    "pic": "66f1449994.jpg",
                    "gender": "Male"
                }
            }
        },
        "5": {
            "characters": {
                "8": {
                    "id": "8",
                    "title": "Stephen Hawking",
                    "pic": "b8c4f17530.jpg",
                    "gender": "Male"
                },
                "18": {
                    "id": "18",
                    "title": "Alan Turing",
                    "pic": "82b4d84e35.jpg",
                    "gender": "Male"
                },
                "19": {
                    "id": "19",
                    "title": "Albert Einstein",
                    "pic": "a6cd74dbaa.jpg",
                    "gender": "Male"
                },
                "34": {
                    "id": "34",
                    "title": "Brian Cox (prof)",
                    "pic": "92b6005de9.jpg",
                    "gender": "Male"
                },
                "43": {
                    "id": "43",
                    "title": "Richard Feynman",
                    "pic": "5de10d1128.jpg",
                    "gender": "Male"
                }
            }
        },
        "6": {
            "characters": {
                "12": {
                    "id": "12",
                    "title": "Jeff Koons",
                    "pic": "8e3ca5f497.jpg",
                    "gender": "Male"
                },
                "20": {
                    "id": "20",
                    "title": "Salvador Dali",
                    "pic": "b5bafb7934.jpg",
                    "gender": "Male"
                },
                "25": {
                    "id": "25",
                    "title": "Rembrandt",
                    "pic": "73e2710029.jpg",
                    "gender": "Male"
                },
                "49": {
                    "id": "49",
                    "title": "Vincent Van Gough",
                    "pic": "6ee455ab28.jpg",
                    "gender": "Male"
                }
            }
        }
    }
}

]

我正在尝试解决我的 iOS 开发人员想要排序的问题......显然 "{"packs":{"9": " 9 是错误的并且不遵循 key:value JSON 结构。我到底如何使用 DB 表 1 中每个结果集的唯一标识符创建正确的 PHP 数组或对象?

结果的结构应该是这样的:

data_db_1:1

data_db_2:id data_db_2:title data_db_2:pic data_db_2:gender

data_db_1:2

data_db_2:id data_db_2:title data_db_2:pic data_db_2:gender

data_db_1:3

data_db_2:id data_db_2:title data_db_2:pic data_db_2:gender

data_db_1:4 data_db_2:id data_db_2:title data_db_2:pic data_db_2:gender

看起来像这样:

     {
"id": "9",
"title": "24",
"credits": "100",
"character": [
    {
        "id": "50",
        "title": "Jack Bauer",
        "pic": "68bcbe014c.jpg",
        "gender": "Male"
    },
    {
        "id": "50",
        "title": "Jack Bauer",
        "pic": "68bcbe014c.jpg",
        "gender": "Male"
    },
    {
        "id": "50",
        "title": "Jack Bauer",
        "pic": "68bcbe014c.jpg",
        "gender": "Male"
    },
    {
        "id": "50",
        "title": "Jack Bauer",
        "pic": "68bcbe014c.jpg",
        "gender": "Male"
    }
]

}

我在网上找不到与此相关的分配。我能想到解决它的唯一方法是使用 json_encode() 和 echo 以及一堆 concat 分别从 PHP 数组中创建每个部分。当然 json_encode() 应该能够从一个简单的 php 数组、一个复杂的 php 多维数组或一个 PHP 对象创建正确的 JSON 而不费吹灰之力???


我的 php 函数按要求执行此操作:

$data_ar = output_pack_data($pack_id);

echo "[".json_encode($data_ar)."]";         // first bit of dirty here

function output_pack_data($pack_id = false)
{
global $db;

$output_keys = true; //false;

if($pack_id != false)
{
    $q = "WHERE id='{$pack_id}' AND active = '1'";                                                          // select the relevant pack ID
}
else
{
    $q = "WHERE active='1' ORDER BY order_num ASC";                                                         // select all pack ids
}

$rs = $db->rs("whoami_packs",$q);

$pack_obj = new stdClass();                                                                                 // declare new std class object here......

$data = array();                                                                                            // prep new array to hold the data

while($rs && $r = $db->fetch($rs))                                                                          // loop thorugh each pack id
{
    $pack_obj->packs->id = $r->id;                                                                      // add the pack title
    $pack_obj->packs->title = $r->title;                                                                        // add the pack title
    $pack_obj->packs->credits = $r->credits;                                                                    // add the required credits to access 

    $packs_rs = $db->rs("whoami_characters","WHERE pack_id='{$r->id}' AND active = '1'");                   // get the character data relevant for this pack

    $i=0;

    while($packs_rs && $pack_r = $db->fetch($packs_rs))                                                     // loop through the character data
    {   
        $id = $r->id;

        if($output_keys == false)
        {
            $data['packs'][$r->id]['characters'][$pack_r->id][$pack_r->title][$pack_r->pic][$pack_r->gender] = true;    // build the array
        }
        else
        {
            $data['packs'][$r->id]['characters'][$pack_r->id]['id'] = $pack_r->id;                  // build the array
            $data['packs'][$r->id]['characters'][$pack_r->id]['title'] = str_out($pack_r->title);                   // build the array
            $data['packs'][$r->id]['characters'][$pack_r->id]['pic'] = $pack_r->pic;
            $data['packs'][$r->id]['characters'][$pack_r->id]['gender'] = ($pack_r->gender = 'm') ? "Male" : "Female";
        }
    }
}

return $data;                                                                                               // return the array

}

4

4 回答 4

1

函数中有一些多余的代码。当你有非连续(数字)索引时,json_encode 不会使用 [x,y,z] 编码,而是使用对象表示法。
显然,您的同事希望将 ID 作为每个对象的属性,而不是作为对象的键。因此,只需通过其 id 删除引用数组元素,但首先创建完整的数组,然后通过 $parent[] 将其附加到其父级。通过这种方式,您可以获得一个具有连续数字 id 的数组 -> json_encode() 创建一个数组表示法。
(未经测试,我懒得从原始问题中提供的 json 输出构建 sql 测试数据)

function output_pack_data($pack_id=false)
{
    global $db;
    $data = array();

    if($pack_id != false) {
        $q = "WHERE id='{$pack_id}' AND active = '1'";
    }
    else {
        $q = "WHERE active='1' ORDER BY order_num ASC";
    }

    $rs_packs = $db->rs("whoami_packs", $q);    
    while($rs_packs && ($rec_pack=$db->fetch($rs_packs)) ) {
        $pack = array(
            'id'=>$rec_pack->id,
            'title'=>$rec_pack->title,
            'credits'=>$rec_pack->credits,
            'characters'=>array()
        );

        $rs_chars = $db->rs("whoami_characters","WHERE pack_id='{$pack->id}' AND active = '1'");
        while($rs_chars && ($rec_char=$db->fetch($rs_chars)) ) {
            $pack['characters'][] = array(
                'id' => $rec_char->id,
                'title' => str_out($rec_char->title),
                'pic' => $rec_char->pic,
                'gender' => 'm'==$rec_char->gender ? "Male" : "Female"
            );
        }
        $data[] = $pack;
    }

    return $data;
}

请阅读https://en.wikipedia.org/wiki/Join_%28SQL%29http://www.w3schools.com/sql/sql_join.asp

于 2012-08-13T15:00:53.297 回答
0

抱歉,这是评论而不是答案(再次)。

我认为 iOS 开发人员(例如我自己)所说的是您使用每个对象的 id 来定义每个对象,而不是键。

您的示例和开发人员的预期输出都是正确的,但是问题在于信息的实际结构。

如果您前往http://json.org/example.html查看 JSON 数据结构的一些示例,可能会更清楚一些。

让我们在 XML 中看看这个。如果将以下 JSON 转换为 XML:

[
{
    "1": {
        "id": "1",
        "title": "Jack Bauer",
        "pic": "68bcbe014c.jpg",
        "gender": "Male"
    }
},
{
    "2": {
        "id": "2",
        "title": "Jack Bauer",
        "pic": "68bcbe014c.jpg",
        "gender": "Male"
    }
}
]

您将得到:

<?xml version="1.0" encoding="UTF-8" ?>
    <1>
        <id>1</id>
        <title>Jack Bauer</title>
        <pic>68bcbe014c.jpg</pic>
        <gender>Male</gender>
    </1>
    <2>
        <id>2</id>
        <title>Jack Bauer</title>
        <pic>68bcbe014c.jpg</pic>
        <gender>Male</gender>
    </2>
</xml>

简而言之,虽然在这两种情况下都结构正确,但数据放置不正确。<1> 和 <2> 节点应该是同一个key,这个原则遵循大多数标准(比如RSS)。

查看您的开发人员的要求,他想要(在 JSON 和 XML 示例中):

{
"character": [
    {
        "id": "1",
        "title": "Jack Bauer",
        "pic": "68bcbe014c.jpg",
        "gender": "Male"
    },
    {
        "id": "2",
        "title": "Jack Bauer",
        "pic": "68bcbe014c.jpg",
        "gender": "Male"
    }
]
}

并作为 XML:

<?xml version="1.0" encoding="UTF-8" ?>
<character>
    <id>1</id>
    <title>Jack Bauer</title>
    <pic>68bcbe014c.jpg</pic>
    <gender>Male</gender>
</character>
<character>
    <id>2</id>
    <title>Jack Bauer</title>
    <pic>68bcbe014c.jpg</pic>
    <gender>Male</gender>
</character>
</xml>

第二个示例的结构显然更有效,因为键(字符)定义了每个值,而不是每个值本身的 id。

于 2012-08-13T14:39:10.137 回答
0

因此,如果 json_encode() 是一个简单的递增计数器,它们似乎会忽略键值......

这个功能:

function output_pack_data($pack_id = false)
{
global $db;

$output_keys = true; //false;

if($pack_id != false)
{
    $q = "WHERE id='{$pack_id}' AND active = '1'";                                                          // select the relevant pack ID
}
else
{
    $q = "WHERE active='1' ORDER BY order_num ASC";                                                         // select all pack ids
}

$rs = $db->rs("whoami_packs",$q);

$data = array();                                                                                            // prep new array to hold the data

$i = 0;    // AHA!

while($rs && $r = $db->fetch($rs))                                                                          // loop through each pack id
{
    $data[$i]['pack_id'] = $r->id;  
    $data[$i]['title'] = $r->title;                                                                     // add the pack title
    $data[$i]['credits'] = $r->credits;                                                                 // add the required credits to access 

    $chars_rs = $db->rs("whoami_characters","WHERE pack_id='{$r->id}' AND active = '1'");                   // get the character data relevant for this pack

    $ii = 0;           // AHA!

    while($chars_rs && $char_r = $db->fetch($chars_rs))                                                     // loop through the character data
    {   
        if($output_keys == false)
        {
            $data[$i]['characters'][$ii][$char_r->title][$char_r->pic][$char_r->gender] = true; // build the array
        }
        else
        {
            $data[(int)$i]['characters'][(int)$ii]['id'] = str_out($char_r->id);                    // build the array
            $data[(int)$i]['characters'][(int)$ii]['title'] = str_out($char_r->title);                  // build the array
            $data[(int)$i]['characters'][(int)$ii]['pic'] = $char_r->pic;
            $data[(int)$i]['characters'][(int)$ii]['gender'] = ($char_r->gender = 'm') ? "Male" : "Female";
        }
        $ii++;
    }

    $i++;
}

return $data;                                                                                               // return the array

}

将返回所需的结果。奇怪的是,文档中没有提到它!哦,好吧,现在排序!希望这可以帮助其他人解决这个问题......注意使用 (int) 以确保 $i 或 $ii 计数器是正确的整数。在这种情况下使用 DB ID 将不起作用,它们将被添加到输出中。

于 2012-08-13T19:22:36.803 回答
0

使用该选项JSON_FORCE_OBJECT(自 PHP 5.3.0 起可用,请参阅此处)将强制json_encode创建一个有效的 JSON 对象

于 2014-05-18T01:57:36.367 回答