What's wrong with this php foreach code? (merged array)
Question by Mouse Hello
$db = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$items = 'SELECT items FROM menus';
$itemLink = 'SELECT itemLink FROM menus';
$itemQuery = $db->query($items);
$linkQuery = $db->query($itemLink);
$fetchItem = $itemQuery->fetch(PDO::FETCH_ASSOC);
$fetchLink = $linkQuery->fetch(PDO::FETCH_ASSOC);
$merged = array_merge($fetchItem,$fetchLink);
foreach($merged as $key=>$value){
echo "${key} => ${value} <br />";
}
This is what it looks like in the database:
items |itemLink
----------------------
Kill Bill|Kill Bill link
Preman |Preman link
So, the expected output, or at least what I thought must be this:
items => Kill Bill
items => Preman
itemLink => Kill Bill Link
itemLink => Preman Link
But the resulted output from the code is this:
items => Kill Bill
itemLink => Kill Bill Link
It’s missing the other items and itemLink
So, how do I achieve the output that I want?
Answer by Sirko
$fetchItem = $itemQuery->fetch(PDO::FETCH_ASSOC);
$fetchLink = $linkQuery->fetch(PDO::FETCH_ASSOC);
This only fetches the first row of each resultset. You need fetchAll:
$fetchItem = $itemQuery->fetchAll(PDO::FETCH_ASSOC);
$fetchLink = $linkQuery->fetchAll(PDO::FETCH_ASSOC);
and adjust the rest of your code.
foreach($merged as $entry) {
foreach( $entry as $key => $value ) {
echo "${key} => ${value} <br />";
}
}
EDIT:
The call of fetch only retrieved the first row of the resultset, whereas fetchAll parses the complete resultset into an Array. So the Objects look like this afterwards:
Array(
[0] => { 'items' => 'Kill Bill' },
[1] => { 'items' => 'Preman' }
)
Array(
[0] => { 'itemLink' => 'Kill Bill' },
[1] => { 'itemLink' => 'Preman' }
)
array_merge concatenate both arrays to the following:
Array(
[0] => { 'items' => 'Kill Bill' },
[1] => { 'items' => 'Preman' },
[2] => { 'itemLink' => 'Kill Bill' },
[3] => { 'itemLink' => 'Preman' }
)
So we now have a two dimensional array. To traverse the values we need first to select each $entry, which is done in the outer foreach and can afterwards access the key/value structure in the inner foreach.
As pointed out in the other comment: If you want to preserve the connection between itemsand itemLink, you should change the query in the first place to
SELECT items, itemLink FROM menus
Answer by Starx
You can use simple array_combine() function to do what you are trying to do now.
$merged = array_combine($fetchItem, $fetchLink);
This will make all the item from $fetchItem as keys to the item from $fetchLink.