简体   繁体   English

PHP多维数组(或对象)为JSON

[英]PHP multidimensional array (or object) to JSON

I have 2 DB tables. 我有2个DB表。 table 2 is relational to table 1. 表2与表1相关。

In php I am building a multidimensional array to hold the data key/values. 在PHP中,我正在构建一个多维数组来保存数据键/值。

because PHP needs to have unique "keys" MY JSON is looking like this: 因为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"
                }
            }
        }
    }
}

] ]

I am trying to solve a problem that my iOS dev wants sorting... apparently the "{"packs":{"9": " 9 is wrong and does not follow the key:value JSON structure. 我正在尝试解决我的iOS开发人员想要排序的问题...显然“ {” packs“:{” 9“:” 9错误,并且不遵循key:value JSON结构。 How on earth do I create a correct PHP array or object for that matter with the unique identifier for each of the result sets from DB table 1? 我到底该如何为这个问题创建一个正确的PHP数组或对象,并为其具有来自数据库表1中每个结果集的唯一标识符?

the result should be structured like this: 结果应如下所示:

data_db_1:1 data_db_1:1

data_db_2:id data_db_2:title data_db_2:pic data_db_2:gender data_db_2:id data_db_2:标题data_db_2:pic data_db_2:性别

data_db_1:2 data_db_1:2

data_db_2:id data_db_2:title data_db_2:pic data_db_2:gender data_db_2:id data_db_2:标题data_db_2:pic data_db_2:性别

data_db_1:3 data_db_1:3

data_db_2:id data_db_2:title data_db_2:pic data_db_2:gender data_db_2:id data_db_2:标题data_db_2:pic data_db_2:性别

data_db_1:4 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:标题data_db_2:pic data_db_2:性别

and look like this: 看起来像这样:

     {
"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"
    }
]

} }

I cant find allot on the web relating to this. 我在网上找不到与此相关的分配。 The only way I can think to solve it is to create each part seperately from PHP arrays using json_encode() and echo and a mess of concat. 我想解决的唯一方法是使用json_encode()和echo和一堆混乱的东西从PHP数组中分别创建每个部分。 Surely json_encode() should be capable of creating correct JSON from a simple php array, a complex php multidimensional array or a PHP object without breaking a sweat??? 当然json_encode()应该能够从简单的php数组,复杂的php多维数组或PHP对象创建正确的JSON,而不会费劲?


my php function to do this as requested: 我的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

} }

There's some superfluous code in the function. 函数中有一些多余的代码。 And when you have non-consecutive (numerical) indices json_encode will not use an [x,y,z] encoding but an object notation. 而且,当您拥有非连续(数字)索引时,json_encode将不使用[x,y,z]编码,而是使用对象表示法。
Apparently your colleague wants the IDs as properties of each object not as the key to an object. 显然,您的同事希望将ID作为每个对象的属性,而不是作为对象的键。 Therefore just drop referencing the array element via its id but first create the complete array then append it to its parent via $parent[]. 因此,只需通过其id删除对数组元素的引用,但首先创建完整的数组,然后通过$ parent []将其附加到其父级。 This way you get an array with sequential numeric ids -> json_encode() creates an array notation. 这样,您将获得具有顺序数字ID的数组-> json_encode()创建数组符号。
(untested, i'm too lazy to build sql test data from the json output provided in the original question) (未经测试,我太懒了,无法从原始问题中提供的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;
}

And please have a read of https://en.wikipedia.org/wiki/Join_%28SQL%29 and http://www.w3schools.com/sql/sql_join.asp 并且,请阅读https://en.wikipedia.org/wiki/Join_%28SQL%29http://www.w3schools.com/sql/sql_join.asp

Sorry, this is a comment and not an answer (again). 抱歉,这是评论,而不是答案(再次)。

I think what the iOS developer (such as myself) is saying is that you are using the id of each object to define each object, and not a key. 我认为iOS开发人员(例如我自己)在说的是,您使用的是每个对象的ID来定义每个对象,而不是键。

Your example and your developer's expected output are both correct, however it's the actual structure of the information that's the issue. 您的示例和开发人员的预期输出都是正确的,但是问题的关键是信息的实际结构。

If you head over to http://json.org/example.html to see some examples of JSON data structuring it might be made a little clearer. 如果您转到http://json.org/example.html来查看JSON数据结构的一些示例,则可能会更清楚一些。

Let's look at this in XML. 让我们用XML来看一下。 If you convert the following JSON into 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"
    }
}
]

You will be left with: 您将剩下:

<?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>

Simply put, although it is correctly structured in both cases, the data placement is not correct. 简而言之,尽管在两种情况下结构都正确,但是数据放置不正确。 the <1> and <2> nodes should be the same key, this principle follows most standards (such as RSS). <1>和<2>节点应该是相同的密钥,此原则遵循大多数标准(例如RSS)。

Looking at your developer's requirements, he wants (in JSON and XML examples): 查看您的开发人员的需求,他想要(在JSON和XML示例中):

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

and as XML: 并作为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>

The second examples are clearly structured more efficiently, since the key (character) defines each value, and not the id of each value itself. 由于键(字符)定义了每个值,而不是每个值本身的id,因此显然可以更有效地构造第二个示例。

So it seems that json_encode() will ignore the key values if they are a simple incrementing counter.... 因此,如果json_encode()是一个简单的递增计数器,它似乎将忽略键值。

this function: 这个功能:

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

} }

will return the desired result. 将返回所需的结果。 Odd that and no mention of it in the documentation! 奇怪的是,在文档中没有提及! oh well, sorted for now! 哦,好,现在排序! Hope this helps anyone else with this problem.... note the use of (int) to make sure the $i or $ii counters are correct integers. 希望这对解决此问题的其他人有帮助。...请注意(int)的使用,以确保$ i或$ ii计数器是正确的整数。 Using the DB IDs in this case will not work and they will get added to the output. 在这种情况下,无法使用数据库ID,它们将被添加到输出中。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM