PHP: For each different key value, group together - php

I have this mysql sample table:
+----+---------------+-------+
| id | company | value |
+----+---------------+-------+
| 1 | google | 50 |
+----+---------------+-------+
| 2 | microsoft | 24 |
+----+---------------+-------+
| 3 | google | 12 |
+----+---------------+-------+
| 4 | microsoft | 89 |
+----+---------------+-------+
| 5 | stackoverflow | 45 |
+----+---------------+-------+
And I want to print it as such so that they are grouped by company:
<ul class="google">
<li>50</li>
<li>12</li>
</ul>
<ul class="microsoft">
<li>24</li>
<li>89</li>
</ul>
<ul class="stackoveflow">
<li>45</li>
</ul>
This is my current code:
$resultx = mysql_query();
$temp=0;
$p = array();
while ($row = mysql_fetch_array($resultx)) {
$p[$temp]['id']=$row['id'];
$p[$temp]['company']=$row['company'];
$p[$temp]['value']=$row['value'];
$temp++;
}
foreach ($p as $obj) {
echo '<ul class="'.$obj["company"].'"><li>'.$obj["value"].'</li></ul>';
};
But my code prints all the company together.
EDIT:
I want to group the company in different UL's.
I would assume that I would have to use another foreach inside my foreach.

When building your array, make the key of the array be the company name or company id. Since I don't see a company id in your query, I will go with name. Now have it be a multidemsional array, with the inner array beging the values.
$resultx = mysql_query();
$p = array();
while ($row = mysql_fetch_array($resultx)) {
$p[$row['company']]['id']=$row['id'];
$p[$row['company']]['company']=$row['company'];
$p[$row['company']]['values'][]=$row['value'];
}
foreach ($p as $obj) {
echo '<ul class="'.htmlspecialchars($obj["company"]).'">';
foreach ($obj['values'] as $value) {
echo '<li>'.htmlspecialchars($value).'</ul>';
}
echo '</ul>';
};

Let us begin:
SELECT * FROM `yourTableName` ORDER BY `company`
Then you do this:
for($i = 0; $i<sizeOf($p); $i++)
{
if ($p[$i] == 0 || $p[$i]['company'] != $p[$i-1]['company'])
echo '<ul class="'.$obj["company"].'">';
ecoh '<li>'.$obj["value"].'</li>';
if ($p[$i] == 0 || $p[$i]['company'] != $p[$i-1]['company'])
echo '</ul>';
}

$resultx = mysql_query();
$temp=0;
$companies = array();
while ($row = mysql_fetch_array($resultx)) {
$companies[$row['company']][]=$row;
}
foreach ($companies as $company=>$values) {
echo '<ul class="'.$company.'">';
foreach($values as $value){
echo '<li>'.$value["value"].'</li>';
}
echo'</ul>';
}
There are of course other ways to do it, to make it simple I used 2 different loops.

$companies = array();
//One array that will have companies' names as keys
// and the value would be an array of values.
$resultx = mysql_query();
while ($row = mysql_fetch_array($resultx)) {
$companies[ $row['company'] ][] = $row['value'];
}
foreach ($companies as $company => $values) { //Loop the companies
echo '<ul class="'.$company.'">';
foreach($values as $value) //Loop the values of that company
{
echo '<li>'.$value.'</li>';
}
echo '</ul>';
}
** Haven't tested it.

I hope that this will solve your problem
$p = array(array());
while ($row = mysql_fetch_array($resultx)) {
$p[$row['company']][] = $row['value'];
}
foreach ($p as $key => $obj) {
echo '<ul class="'.$key.'">';
foreach ($obj as $val) {
echo '<li>'.$val.'</li>';
}
echo '</ul>';
};

Related

How can I make this function simpler? Unknown array depth

I am back with another question.
I am trying to go through an array and list all the items that match the parent ID of the category and subcategory then list the items in the inventory for the subcategory.
I need to show all items from the category when a button is clicked.
I have a tree view like this
When you click on M8 or 316SS it'll either show the items in M8 or it'll show all the items in the 316SS category.
I need to do this but on every level as well however the code I am currently using doesn't work for it.
Which is this
<?php
include 'classLoader.php';
if (isset($_GET['id']) && !empty($_GET['id'])) {
$items = DB::query("SELECT * FROM inventory WHERE parent=:parent", array(":parent" => $_GET['id']));
if (!empty($items)) {
$data = array();
foreach ($items as $item_key => $item) {
$data["data"][] = array('<i class="icon material-icons">open_in_new</i><a class="link icon-only"><i class="icon material-icons">edit</i></a>', $item['item'], $item['supplier_product_code'], $item['price_per_unit'], $item['current_stock'], $item['category'], '<a class="link icon-only"><i class="icon material-icons">delete</i></a>');
}
header("Content-Type: application/json");
echo json_encode($data, JSON_PRETTY_PRINT);
} else {
$categories = DB::query("SELECT * FROM categories WHERE parent=:id", array(":id" => $_GET['id']));
$data = array();
foreach ($categories as $cat_key => $cat) {
$items = DB::query("SELECT * FROM inventory WHERE parent=:parent", array(":parent" => $cat['id']));
foreach ($items as $item_key => $item) {
$data["data"][] = array('<i class="icon material-icons">open_in_new</i><a class="link icon-only"><i class="icon material-icons">edit</i></a>', $item['item'], $item['supplier_product_code'], $item['price_per_unit'], $item['current_stock'], $item['category'], '<a class="link icon-only"><i class="icon material-icons">delete</i></a>');
}
}
header("Content-Type: application/json");
echo json_encode($data, JSON_PRETTY_PRINT);
}
}
?>
When that didn't work I tried the following code (Cut down but it is pretty much duplicated like 10 times). This code works however it is resource intensive and only goes so many deep. I need one that will continue following it until its got nowhere else to go.
<?php
include 'classLoader.php';
if (isset($_GET['id']) && !empty($_GET['id'])) {
$items = DB::query("SELECT * FROM categories WHERE parent=:id", array(":id" => $_GET['id']));
$d = array();
if (!empty($items)) {
foreach ($items as $item_key => $item) {
$d[] = $item['category_name'];
$subItems = DB::query("SELECT * FROM categories WHERE parent=:catID", array(":catID" => $item['id']));
foreach ($subItems as $item_key => $item) {
$d[] = $item['category_name'];
$subItems = DB::query("SELECT * FROM categories WHERE parent=:catID", array(":catID" => $item['id']));
foreach ($subItems as $item_key => $item) {
$d[] = $item['category_name'];
$subItems = DB::query("SELECT * FROM categories WHERE parent=:catID", array(":catID" => $item['id']));
foreach ($subItems as $item_key => $item) {
$d[] = $item['category_name'];
$subItems = DB::query("SELECT * FROM categories WHERE parent=:catID", array(":catID" => $item['id']));
foreach ($subItems as $item_key => $item) {
$d[] = $item['category_name'];
$subItems = DB::query("SELECT * FROM inventory WHERE parent=:catID", array(":catID" => $item['id']));
}
}
}
}
}
}
header("Content-Type: application/json");
echo json_encode($d, JSON_PRETTY_PRINT);
}
?>
Is there a way to make this function "recursive" in a sense? The database is like this
# categories
| category_name | parent |
| Fasteners | 0 |
| Bolts | 1 |
| 316SS | 2 |
| M8 | 3 |
# inventory
| item | parent |
| 20 | 0 |
| 30 | 1 |
These tables both have over 3000 unique items in them.
Sorry for the very low quality question.
Solved.
I used the following code.
$cats = DB::query("SELECT * FROM categories");
$r = fetch_recursive($cats, $_GET['id']);
foreach ($r as $cat_key => $cat) {
$items = DB::query("SELECT * FROM inventory WHERE parent=:parent", array(":parent" => $cat['id']));
foreach ($items as $item_key => $item) {
$data["data"][] = array('<i class="icon material-icons">open_in_new</i><a class="link icon-only"><i class="icon material-icons">edit</i></a>', $item['item'], $item['supplier_product_code'], $item['price_per_unit'], $item['current_stock'], $item['category'], '<a class="link icon-only"><i class="icon material-icons">delete</i></a>');
}
}
function fetch_recursive($src_arr, $id, $parentfound = false, $cats = array())
{
foreach($src_arr as $row)
{
if((!$parentfound && $row['id'] == $id) || $row['parent'] == $id)
{
$rowdata = array();
foreach($row as $k => $v)
$rowdata[$k] = $v;
$cats[] = $rowdata;
if($row['parent'] == $id)
$cats = array_merge($cats, fetch_recursive($src_arr, $row['id'], true));
}
}
return $cats;
}

How to show json data with column name in php

i have some JSON data
i am able to retrieve data out of it but i want data to be displayed with columns
this the JSON
{"ObjectId":43,"ObjectName":"MEGA MELA","ObjectTitle":"Event Created by API","ObjectDescription":"NEW EVENT BY API","ObjectLabel":"","ObjectTypeId":33,"MaxFieldsExpected":5,"ObjectValueType":null,"ObjectControlType":"","IsDeleted":true,"CreatedDate":"2019-05-22T07:56:03.767","CreatedBy":null,"EditedDate":null,"EditedBy":null,"DeletedDate":null},{"ObjectId":44,"ObjectName":"Event x11","ObjectTitle":"Event Created by API","ObjectDescription":"NEW EVENT BY API","ObjectLabel":"","ObjectTypeId":33,"MaxFieldsExpected":5,"ObjectValueType":null,"ObjectControlType":"","IsDeleted":true,"CreatedDate":"2019-05-23T00:33:50.7","CreatedBy":null,"EditedDate":null,"EditedBy":null,"DeletedDate":null}]}
here is what i am doing right now
$jsonData = json_decode($data, TRUE);
foreach ($jsonData as $d) {
foreach ($d as $ins) {
echo "<h3>".$ins['ObjectName']."</h3>";
echo "<h3>".$ins['ObjectDescription']."</h3>";
}
}
OutPut:
MEGA MELA
NEW EVENT BY API
Event x11
NEW EVENT BY API
i want it in this format
ObjectId | ObjectName | ObjectTitle | ObjectDescription | ObjectLabel | ObjectTypeId | MaxFieldsExpected | ObjectValueType | ObjectControlType | IsDeleted | CreatedDate | CreatedBy | EditedDate | EditedBy
43 | MEGA MELA | Event Created by API | NEW EVENT BY API | ..............................................................................
above i am getting data with help of array key now i want extracting keys from JSON like ObjectId or ObjectName making them header of table and showing all the data in columns
on the above example, you can use the key to print the filed name and value will be the data.
here we can loop the field names first to create the heading
I am using table here.
<table>
<?php foreach ($d as $ins) { ?>
//printing field heads
<tr>
<?php
foreach ($ins as $key=>$value) {
echo "<td><h3>".$key."</h3></td>";
} ?>
</tr>
//printing value row
<tr>
<?php
foreach ($ins as $key=>$value) {
echo "<td><h3>".$value."</h3></td>";
} ?>
</tr>
} ?>
</table>
Used an old gist for array2table from here : http://www.aidanlister.com/2004/04/converting-arrays-to-human-readable-tables/
<?php
function array2table($array, $recursive = false, $null = ' ')
{
// Sanity check
if (empty($array) || !is_array($array)) {
return false;
}
if (!isset($array[0]) || !is_array($array[0])) {
$array = array($array);
}
// Start the table
$table = "<table>\n";
// The header
$table .= "\t<tr>";
// Take the keys from the first row as the headings
foreach (array_keys($array[0]) as $heading) {
$table .= '<th>' . $heading . '</th>';
}
$table .= "</tr>\n";
// The body
foreach ($array as $row) {
$table .= "\t<tr>" ;
foreach ($row as $cell) {
$table .= '<td>';
// Cast objects
if (is_object($cell)) { $cell = (array) $cell; }
if ($recursive === true && is_array($cell) && !empty($cell)) {
// Recursive mode
$table .= "\n" . array2table($cell, true, true) . "\n";
} else {
$table .= (strlen($cell) > 0) ?
htmlspecialchars((string) $cell) :
$null;
}
$table .= '</td>';
}
$table .= "</tr>\n";
}
$table .= '</table>';
return $table;
}
$data ='[{"ObjectId":43,"ObjectName":"MEGA MELA","ObjectTitle":"Event Created by API","ObjectDescription":"NEW EVENT BY API","ObjectLabel":"","ObjectTypeId":33,"MaxFieldsExpected":5,"ObjectValueType":null,"ObjectControlType":"","IsDeleted":true,"CreatedDate":"2019-05-22T07:56:03.767","CreatedBy":null,"EditedDate":null,"EditedBy":null,"DeletedDate":null},{"ObjectId":44,"ObjectName":"Event x11","ObjectTitle":"Event Created by API","ObjectDescription":"NEW EVENT BY API","ObjectLabel":"","ObjectTypeId":33,"MaxFieldsExpected":5,"ObjectValueType":null,"ObjectControlType":"","IsDeleted":true,"CreatedDate":"2019-05-23T00:33:50.7","CreatedBy":null,"EditedDate":null,"EditedBy":null,"DeletedDate":null}]';
$jsonData = json_decode($data, TRUE);
echo array2table($jsonData);
?>
DEMO: https://3v4l.org/0n27Y
Second foreach should look like: foreach ($d as $key => $ins) then at $key variable you get your indexes.

How to echo number format grouping array inside foreach using PHP ?

My question is referring to my previous question in this link How to echo specific multiple same records only once using foreach loops in PHP? .
This is my current code
Code :
$sqlTXT = "SELECT * FROM TABLE";
$arr_old = DB::getInstance()->FetchArray($sqlTXT);
if(count($arr_old) > 0)
{
$arr = array();
foreach($arr_old as $key => $item)
{
if(!array_key_exists($item['ACCOUNT_NUMBER'], $arr))
{
$arr[$item['ACCOUNT_NUMBER']][$item['ACCOUNT_NUMBER']]['ACCOUNT'] = $item['ACCOUNT'];
$arr[$item['ACCOUNT_NUMBER']][$item['ACCOUNT_NUMBER']]['CATEGORY'] = $item['CATEGORY'];
$arr[$item['ACCOUNT_NUMBER']][$item['ACCOUNT_NUMBER']]['VALUE'] = $item['VALUE'];
$arr[$item['ACCOUNT_NUMBER']][$item['ACCOUNT_NUMBER']]['FUND'] = $item['FUND'];
$arr[$item['ACCOUNT_NUMBER']][$item['ACCOUNT_NUMBER']]['AMOUNT'] = $item['AMOUNT'];
}
else
{
$arr[$item['ACCOUNT_NUMBER']][$item['ACCOUNT_NUMBER']]['CATEGORY'] .= ",".$item['CATEGORY'];
$arr[$item['ACCOUNT_NUMBER']][$item['ACCOUNT_NUMBER']]['VALUE'] .= ",".$item['VALUE'];
}
}
ksort($arr, SORT_NUMERIC);
echo "<table>";
echo "<tr>";
echo "<td>ACCOUNT</td>";
echo "<td>CATEGORY</td>";
echo "<td>VALUE</td>";
echo "<td>FUND</td>";
echo "<td>AMOUNT</td>";
echo "</tr>";
foreach($arr as $key => $item)
{
// Display Category
$xpl = explode(",",$item[$key]['CATEGORY']);
$n_category = "";
foreach($xpl as $b => $a){
$n_category .= ($b!=0) ? "<br>".$a : $a ;
}
// Display Value
$trl = explode(",",$item[$key]['VALUE']);
$n_value = "";
foreach($trl as $c => $d){
$n_value .= ($c!=0) ? "<br>".$d : $d ;
// $new = number_format($n_value, 2, '.', ',');
}
echo "<tr>";
echo "<td>".$item[$key]['ACCOUNT']."</td>";
echo "<td>".$n_category."</td>";
echo "<td>".$new."</td>";
echo "<td>".$item[$key]['FUND']."</td>";
echo "<td>".$item[$key]['AMOUNT']."</td>";
echo "</tr>";
}
echo "</table>";
}
And the output as shown as below.
Output :
ACCOUNT CATEGORY VALUE FUND AMOUNT
0001 Category1 10000 BIN 300,000.00
Category2 0
Category3 500
Category4 15000
0002 Category1 8500 BIN 70,000.00
Category2 7000
Category3 100
Category4 0
But my current issue is I can't convert the VALUE column into 2 decimals format. When I added code
$new = number_format($n_value, 2, '.', ',');
The output only shows the first value of array.
I hope that someone can help me to solve this issue.
Thanks in advance.
You need to convert each value in the column independently. Try changing your foreach loop to this:
foreach($trl as $c => $d){
if (is_numeric($d)) $d = number_format($d, 2, '.', ',');
$n_value .= ($c!=0) ? "<br>".$d : $d ;
}

php array replicate format in while loop

I want to output the result of a query so that the format is the same as:
$links = array(
'Link 1' => '/link1',
'Link 2' => '/link2'
);
So the query is
$query = "SELECT * FROM link";
$result = mysql_query($query, $connection) or die(mysql_error());
$row = mysql_fetch_assoc($result)
The field that need to be output are:
$row['link_title'] and $row['url']
This is probably a bit more complex then desired or necessary but would this work for you:
$a = 0;
while ($row = mysql_fetch_assoc($result)) {
foreach ($row as $k => $v) {
// Assumes table column name is 'link_title' for the link title
if ($k == 'link_title') {$title[$a] = $v;}
// Assumes table column name is 'url' for the URL
if ($k == 'url') {$url[$a] = $v;}
}
$a++;
}
$i = 0;
foreach ($title as $t) {
$links[$t] = $url[$i];
$i++;
}
print_r($links);
As #Class stated, if the link_title's never repeat than you could do something like this:
while ($row = mysql_fetch_assoc($result)) {
$array[$row['link_title']] = $row['url'];
}
Since the link_title's were unique both processes output:
Array (
[Moxiecode] => moxiecode.com
[Freshmeat] => freshmeat.com
)
Database table + contents:
id | link_title | url |
---+------------+---------------|
1 | Moxiecode | moxiecode.com |
---+------------+---------------|
2 | Freshmeat | freshmeat.com |
Are you looking for something like this:
$links = array();
while(foo){
$links[$row['link_title']] = $row['url'];
}
OR you can use which might cause overriding if the title is the same like in the example above
$link = array();
$title = array()
while($row = mysql_fetch_assoc($result)){
array_push($title, $row['link_title']);
array_push($link, $row['url']);
}
$links = array_combine($title, $link);
Also use PDO or mysqli functions mysql is deprecated. Here's a tutorial for PDO
EDIT: Example: http://codepad.viper-7.com/uKIMgp I don't know how to create a example with a db but its close enough.
You want to echo out the structure of the array?
foreach ($Array AS $Values => $Keys)
{
echo "Array Key: <b>". $Keys ."</b> Array Value:<b>". $Values ."</b>";
}
This will echo out the structure of your exampled array

How to create php array from MySQL column?

I have such table:
id | name | link
---+--------------------------------------+---------------
1 |SAsasasdsa,Главная страница,Main page | addsad
I want to get array like that:
$arr = array('az'=>'SAsasasdsa','ru'=>'Главная страница','en'=>'Main page');
TRY
$qry = mysql_query('SELECT * FROM table');
//for multiple rows
$row = mysql_fetch_assoc($qry)) { $input[] = $row['name'] }
$key = array('az', 'ru', 'en');
foreach($input as $val) {
$output[] = array_combine($key,explode(',',$val));
}
echo "<pre>"; print_r($output);
Reference
array_combine

Categories