Grouping items in a foreach loop in PHP - php

So, I'm trying to make a sort of user-market type thing. There's a database with item_names, basically describes the virtual items, then there's another table market, where when a user lists one of their items, it's put for sale on the user-user market.
My only problem here is I want to group it by item name, referenced in the item_name table. I know I could do a bunch of if/else statements but that's extraneous not only because there's a lot of items, but also because I will add more items as time goes on. I want the end result to be something like
--[Water for sale]---------------------+
[50 water for sale] [20 water for sale]
[10 water for sale] [10 water for sale]
--[Chips for sale]----------------------+
[50 chips for sale] [20 chips for sale]
[10 chips for sale] [10 chips for sale]
And so on, done dynamically.
Any help?

Fetch data:
$data = array();
while ($row = mysql_fetch_assoc($result)) {
$itemName = $row["item_name"];
if (!array_key_exists($itemName, $data)) {
$data[$itemName] = array();
}
$data[$itemName][] = $row;
}
Display data
foreach ($data as $itemName => $rows) {
echo '<h1>', $itemName, '</h1>';
echo '<ul>';
foreach ($rows as $row) {
echo '<li>', $row["article_name"], '</li>';
}
echo '</ul>';
}

Make sure you order (not group) the results on your SQL query, then the loop will be very simple (assuming PDO, and a column item_name on table item_names):
$sth = $dbh->query ("SELECT * FROM item_names ORDER BY item_name");
$lastname = '';
while ($row = $sth->fetch()) {
if($lastname != $row['item_name']) {
echo '<h1>' . $row['item_name'] . '</h1>';
}
// echo contents for each item here
// remember name from last row
$lastname = $row['item_name'];
}

Related

How to get unique value in foreach loop

I have a table in which I have some products and from them I want to get just unique values. I have a database in which I have values like Kia Picanto, Toyota Corolla, Kia Sportage, BMW Series 6, BMW Series 7 etc. Now I want to show values like Kia, Toyota, BMW. I am trying to search over the internet but didn't find any possible solutions so that's why I ma posting my question here to get the solution.I am using
SQL:
$sql = $db_con->prepare("SELECT `post_title` FROM `panel_product` WHERE `product_type` LIKE '%vehicle%' ORDER BY `post_title`");
$sql->execute();
$menufectures = $sql->fetchAll();
if (count($menufectures) > 0) {
foreach ($menufectures as $key) {
$brand = explode(' ', $key['post_title']);
$brand = $brand[0];
echo $brand.'<br />';
}
}
But I am getting Kia, Kia, Toyota, BMW, BMW. Please let me know if you have any solution for this.
Thanks
You can store the ones you've displayed in an array that you can check while iterating:
// Initialize a new variable
$brands = [];
foreach ($menufectures as $key) {
$brand = explode(' ', $key['post_title']);
$brand = $brand[0];
if (!isset($brands[$brand])) {
// It doesn't exist in the array so echo it and add it to the array
$brands[$brand] = true;
echo $brand.'<br />';
}
}

Accessing results from collect() using neo4j-php-client

The below displays:
Marlena has 12 paintings (which is basically from the docs)
How do I access the data in collect(Paintings)
ex: title
$query = "MATCH (n:Artist)-[:PAINTED]->(Painting) RETURN n.first_name, collect(Painting) as paintings";
$result = $client->run($query);
foreach ($result->getRecords() as $record) {
echo sprintf('%s has %d paintings', $record->value('n.first_name'), count($record->value('paintings')));
echo '<br/>';
}
I would like to display:
Artist Name:
painting title
painting title
etc
I assume this data can be pull from either Painting or paintings. I am just unsure how to put together the query. It will display using print_r and the record so I know the data is coming through.
This should work for you:
$query = "MATCH (n:Artist)-[:PAINTED]->(Painting) RETURN n.first_name, collect(Painting) as paintings";
$result = $client->run($query);
foreach ($result->getRecords() as $record) {
echo sprintf('%s has %d paintings:<br/>', $record->value('n.first_name'), count($record->value('paintings')));
foreach ($record->value('n.paintings') as $painting) {
echo sprintf('- %s<br/>', $painting->value('title'));
}
echo '<br/>';
}
a) I suggest you alias your return values, it is easier to fetch them at the driver level
b) The paintings record value returns an array of Node objects, thus is iterable, no need to count for doing the for loop :
$query = "MATCH (n:Artist)-[:PAINTED]->(Painting) RETURN n.first_name as firstName, collect(Painting) as paintings";
$result = $client->run($query);
foreach($result->records() as $record) {
echo sprintf('%s painted %d paintings', $record->get('firstName'), count($record->get('paintings'))) . PHP_EOL;
foreach ($record->get('paintings') as $painting) {
echo sprintf('%s - %d views', $painting->value('title'), $painting->value('views')) . PHP_EOL;
}
}
I ended up getting it to work with the following:
foreach ($result->getRecords() as $record) {
$fname = $record->values()[0]->get('first_name');
$lname = $record->values()[0]->get('last_name');
echo '<strong>'.$fname.' '.$lname.' painted:</strong><br/>';
for ($x = 0; $x < count($record->values()[1]); $x++) {
print_r($record->values()[1][$x]->get('title'));
echo ' - ';
print_r($record->values()[1][$x]->get('views'));
echo ' views<br/>';
}
echo '<br/>';
}
Which provides the following output:
First Name Last Name painted:
Lumine - 86 views
Pooled Water - 69 views
Still Lake - 125 views
Final Notes
I actually tried code similar to what you suggested during my struggle to get this working. I'm a bit confused why it does not.
So I'm left wondering. Is what I come up with acceptable?

fetch 2 columns from table in 2 array php mysql

I have a table with 6 columns
Sort like:
Database -> kids
|CANDY | COLOR | DRINK | PET | SONG | TOY |
---------------------------------------------------
|cookie | blue | juice | dog | if | ball |
|cake | red | coke | cat | ask | doll |
I want to store
all the candies in one Array called Candy[];
all the colors on color[];
all the drinks on drink[]; etc....
I managed to create the arrays with the columns names with a FORLOOP with these lines, which works fine:
$fieldName = mysqli_fetch_field_direct($result, $i)->name;
${$fieldName} = array();
But when the code gets to the WHILE part, that is also inside the loop, to add the columns items inside the arrays[], it adds only the first element and returns to the FORLOOP, goes and adds one element to the next array[] and jumps to the next array[]....
while($row = mysqli_fetch_array($result)){
//inserts itens in the "$array" with columns name
${$fieldName}[] = $row[$i];
}
If I try to "echo" the arrays[] and don´t put a "BREAK" at the end of the WHILE, It returns an error
"Undefined offset: 0 in line..."
And when I put the "BREAK", it works for:
echo candy[0]; = cookie
but doesn't works for:
echo candy[1]; = Undefined offset: 1 in line...
Here is the whole code:
$sql="SELECT candy, color, drink, pet, song, toy FROM kids";
$result = mysqli_query($con,$sql);
$colNumber = mysqli_num_fields($result);
for($i=0;$i<=$colNumber -1;$i++){
$fieldName = mysqli_fetch_field_direct($result, $i)->name;
echo . $fieldName . "<br /><br />";
//Creates an Array with Coll Name from DB
//with dynamic-variable ${$fieldname}
${$fieldName} = array();
while($row = mysqli_fetch_array($result, MYSQLI_NUM)){
//inserts the received itens into the array ${$fieldName}
${$fieldName}[] = $row[$i];
printf ("%s (%s)\n", $row[$i], $row[1]);
}
echo ${$fieldName}[0];
echo candy[0];
echo ${$fieldName}[1];
echo candy[1];
echo "<hr />";
}
The WHILE code works when it´s not inside a FORLOOP and if I make a query() like:
SELECT candy FROM kids.
But then, like that, I´d need like 600 lines of repeated code to get what I want and copy/paste again and again for each new coll on the DB table.
Any ideas?
I need it to put the arrays inside HTML
<SELECT><OPTION></SELECT> , then use mt_rand() to shuffle and get different "profiles". This won´t be used with kid stuff, that was just an example.
It will be a virtual crime creator that will shuffle the variables to create different crime hypothesis for law school students work on.
I already spent 3 days reading documentation on http://php.net/manual/pt_BR/mysqli-result.fetch-array.php
and "googling" it but couldn't find any answer.
Found a way to do it. I translated the code to English so others can have it. If there is any variable name wrong, fix it using the comments and enjoy!
$sql = "SELECT parquet, defendant, action, modusOperandi, victim, crime FROM crime_elements";
//runs '$sql' query to get database data
$result = mysqli_query($con,$sql);
$collNumber = mysqli_num_fields($result);
echo "ColL Number :" . $collNumber;
// Creates $data Array[]
$data = array();
while($row = mysqli_fetch_array($result)){
//inserts received data into "$data" and makes available by array[]index
$data[] = $row;
}
for($i=0;$i<=$collNumber -1;$i++){
// Gets the column name from the query()
$fieldName = mysqli_fetch_field_direct($result, $i)->name;
echo "</br><b>Coll Name:</b> " . $fieldName . "<br /><br />";
${$fieldName} = array_column($data, $i);
print_r(${$fieldName});
echo "<br /><b>Specified item choice[]:</b> ". ${$fieldName}[2];
echo "<hr />";
}

PHP how to echo the first value of each group in a mysql query list

To better explain my situation, please take a look at this mokeup query result:
Category Item
cat1 Item 1
cat1 Item 2
cat1 Item 3
cat23 Item x
cat23 Item y
cat23 Item z
X apples
X oranges
X bananas
and so on....
I am pulling the data off a mysql database and would like to display the results like this:
Category----Item
cat1 Item 1
Item 2
Item 3
cat23 Item x
Item y
Item z
X apples
oranges
bananas
and so on....
I tried different ways but I am coming up empty. This is the latest attempt:
PHP
//Headers
echo 'Category';
echo ' | ';
echo 'Item';
echo "\n";
$sql = "SELECT `table1`.*, `table2`.* FROM table1 INNER JOIN table2 ON `table1`.`Category` = `table2`.`Category` ORDER BY `table1`.`Category`, `table2`.`Item`";
$dbq = mysql_query( $sql );
$cat = '';
while( $data = mysql_fetch_assoc( $dbq ) ) {
if( !$cat == $data['category'] ) {
$cat = $data['category'];
echo $cat;
echo ' | ';
echo $data['item'];
echo "\n";
}
else {
echo ' ';
echo ' | ';
echo $data['item'];
echo "\n";
}
}
With this code, the current output is:
Category----Item
cat1 Item 1
Item 2
Item 3
Item x
Item y
Item z
apples
oranges
bananas
...rather than the desired output.
I am looking for the most efficient and simple way to echo each category 1 time only. Perhaps this code is not the best way to approach it, but I tried in different ways and my brain right now is shut S_S .
Took me quite some time...
Change
if( !$cat == $data['category'] ) {
To
if( $cat != $data['category'] ) {
Better to concatenate the Items of same category and store it like as Item1,Item2,Item3.
When you want to use this Items use explode() to split and
when ever you want to search in this items for a particular item use mysql's FIND-IN-SET
Not sure what you're looking for as that solution seems like it solves what you need it to do but if you want to be more tolerant of the result orders you can try this:
$concated_data = array();
while( $data = mysql_fetch_assoc( $dbq ) )
{
if ( ! array_key_exists( $data['category'], $concated_data ) )
$concated_data[$data['category']] = array();
array_push($concated_data[$data['category']], $data['item']);
}
foreach ($concated_data as $category => $items)
{
echo $category;
$count = count($items);
for ($i = 0; $i < $count; $i++)
{
if ($i == 0)
echo "\t";
else
echo "\t\t";
echo $items[$i]."\n"; // Items
}
}
Formatting up to you at this point I guess but I think putting the data into an array of arrays is the best way so the top level keys are categories and then the arrays they point to now hold an array of your items. This also doesn't assume that you get results in the same category consecutively.
Sorry code might contain bugs as I haven't coded in PHP in awhile. But basically you should accumulate the items first then go through the accumulated list and output the data.

How to break down a php array with levels?

I have a MySQL table with stock information including what main industry sector and sub sector a stock belongs to (for example the Coca-Cola stock belongs to the industry sector "Consumer Goods" and to the sub sector "Beverages - Soft Drinks".
$SQL = "SELECT name, industrysector, subsector FROM Stocks WHERE economic_indicator_type = 'Stock' GROUP BY industrysector, subsector, name";
$result = mysql_query($SQL) or die ("Error in query: $SQL. " . mysql_error());
while ($row = mysql_fetch_row($result)) {
$stocks[$i]['name'] = $row[0];
$stocks[$i]['industrysector'] = $row[1];
$stocks[$i]['subsector'] = $row[2];
$i++;
}
$stocksTotals = array();
foreach($stocks as $amount) {
$stocksTotals[$amount['industrysector']] = $stocksTotals[$amount['industrysector']].", ".$amount['name'];
}
foreach($stocksTotals as $name => $amount) { echo $name.": ".substr($amount,1)."<br>"; }
My problem is that I don't get the code to handle the third level. I want to first output all of the industry sectors (Basic material for example), then all subsectors (Basic Resources for example) for each industry sector, then all names of the stocks corresponding to each subsector.
Currently I only get industry sector and then the stock name, because I fail to understand how to handle this in the array handling code.
Any advise would be highly appreciated! I have put a image here (http://imageshack.us/photo/my-images/853/mysqltophp.gif/) for better reference.
Thanks!
the foreach loop needs to be like this:
//considering you want the value as "$amount['industrysector'], $amount['name']"
foreach($stocks as $amount) {
// $stocksTotals[$amount['industrysector']] = $amount['industrysector'] .", ".$amount['name'];
echo $amount['industrysector'].": "."$amount['industrysector'], $amount['name']"."<br>";
}
you dont need another foreach loop.
Edit: you would need to change the way you fetch your rows too,
while ($row = mysql_fetch_assoc($result)) {
$stocks[$i]['name'] = $row['name'];
$stocks[$i]['industrysector'] = $row['industrysector'];
$stocks[$i]['subsector'] = $row['industrysector'];
$i++;
}
foreach($stocks as $amount) {
$output = "$amount['industrysector'] : $amount['industrysector'], $amount['subsector']";
if( $amount['name'] !== '' )
$output .= "<br>" . $amount['name'];
";
}

Categories