Not getting expected results through foreach loop - php

I have following table structure
Updates
+----------------------------------------------------------------------------+
| Id | name | category | link | artist | home |
+---------------------------------------------------------------------------+
| 1 | song_1 | single | #### | artist_1 | 1 |
+-------+------------+----------------+-------------+--------------+
| 2 | song_2 | bollywood | #### | artist_2 | 1 |
+-------+------------+----------------+-------------+--------------+
| 3 | song_3 | single | #### | artist_3 | 1 |
+-------+------------+----------------+-------------+--------------+
| 4 | song_4 | bollywood | #### | artist_4 | 1 |
+------------------------------------------------------------------+
My code for fetch results.
<?php $update_list = $db->query('select * from `update` where home = 1 order by id desc LIMIT 0, 10');
foreach($update_list as $field => $value)
{
print_r($value['category']' - ');
if($value['link'] != '') { print_r(''.$value['name'].' - - ');
}
if($value['singers'] != '') {
print_r('['.$value['singers'].']');
} ?>
I'm getting following results
single - song_1- [artist_1]
bollywood - song_2 - [artist_2]
single - song_3 - [artist_3]
bollywood - song_4 - [artist_4]
I want results like this, by above single query.
single - song_1 - [artist_1] > song_3 - [artist_3]
bollywood - song_2 - [artist_2] > song_4 - [artist_4]
Can't figure out how to code it.
Help me please, suggest me a way which php function to use here.

Try the below code if it helps,
<?php
$update_list = $db->query('select * from `update` where home = 1 order by category desc, id desc LIMIT 0, 10');
$currentcategory = false;
foreach($update_list as $field => $value) {
if($currentcategory != $value['category']) {
if($currentcategory != false) {
echo '<br>';
}
echo $value['category'].' - ';
$currentcategory = $value['category'];
}
else {
echo ' > ';
}
if($value['link'] != '') {
echo ''.$value['name'].' - ';
}
if($value['singers'] != '') {
echo '['.$value['singers'].']';
}
} ?>

Related

Generate JSON booleans from Db

I need to generate a JSON String using this format:
{"content":{"brands":1},"brands":[{"id":"1","name":"brand 1","description":"description","icon":"icon","url":"example.com","categories":{"1":"true","2":"true","3":"false","4":"false","5":"false","6":"false"}},{"id":"2","name":"brand2","description":"description","icon":"icon","url":"example.com","categories":{"1":"true","2":"true","3":"false","4":"false","5":"false","6":"false"}}]}
From this tables:
brands:
| id | name | description | icon | url |
|----|--------|-------------|------|-----|
| 1 | name 1 | description | icon | url |
| 2 | name 2 | description | icon | url |
| 3 | name 3 | description | icon | url |
| 4 | name 4 | description | icon | url |
| 5 | name 5 | description | icon | url |
| 6 | name 6 | description | icon | url |
categories:
| id | name | description | icon | url |
|----|--------|-------------|------|-----|
| 1 | name 1 | description | icon | url |
| 2 | name 2 | description | icon | url |
| 3 | name 3 | description | icon | url |
| 4 | name 4 | description | icon | url |
| 5 | name 5 | description | icon | url |
| 6 | name 6 | description | icon | url |
objects:
| id | id_brand | id_category |name | description | icon | url |
|----|----------|-------------|-------|-------------|------|-----|
| 1 | 1 | 1 |name 1 | description | icon | url |
| 2 | 1 | 2 |name 2 | description | icon | url |
| 3 | 2 | 1 |name 3 | description | icon | url |
| 4 | 2 | 2 |name 4 | description | icon | url |
this is my relevant code so far
public function actionBrand($id = null) {
if (empty($id)) {
// Obtiene datos de la base
$sql = "SELECT DISTINCT objects.id_brand AS id, brands.name AS name, brands.description AS description, brands.icon AS icon, brands.url AS url, objects.id_category, categories.name AS category " .
"FROM objects " .
"LEFT JOIN brands ON objects.id_brand = brands.id " .
"LEFT JOIN categories ON objects.id_category = categories.id " .
"ORDER BY objects.id_brand, objects.id_category ";
} else {
// Obtiene datos de la base
$sql = "SELECT DISTINCT objects.id_brand AS id, brands.name AS name, brands.description AS description, brands.icon AS icon, brands.url AS url, objects.id_category, categories.name AS category " .
"FROM objects " .
"LEFT JOIN brands ON objects.id_brand = brands.id " .
"LEFT JOIN categories ON objects.id_category = categories.id " .
"WHERE brands.id = " . (int) $id . " " .
"ORDER BY objects.id_brand, objects.id_category ";
}
$data = Yii::$app->db->createCommand($sql)
->queryAll();
// Obtiene categorias
$categories = Yii::$app->db->createCommand('SELECT id FROM categories ORDER BY id')
->queryAll();
if (!empty($data)) {
// Construye primer registro
$brands[0]['id'] = $data[0]['id'];
$brands[0]['name'] = $data[0]['name'];
$brands[0]['description'] = $data[0]['description'];
$brands[0]['icon'] = $data[0]['icon'];
$brands[0]['url'] = $data[0]['url'];
$total = count($data);
for ($i = 1, $j = 0; $i < $total; $i++) {
if ($brands[$j]['id'] == $data[$i]['id']) {
continue;
} else {
$j++;
$brands[$j]['id'] = $data[$i]['id'];
$brands[$j]['name'] = $data[$i]['name'];
$brands[$j]['description'] = $data[$i]['description'];
$brands[$j]['icon'] = $data[$i]['icon'];
$brands[$j]['url'] = $data[$i]['url'];
}
}
} else {
$brands = array();
}
// Construye y envia JSON
$json['content']['brands'] = count($brands);
$json['brands'] = $brands;
echo json_encode($json);
}
It generates the first part of the JSON that i need, but im stuck at the categories part i need to select the data from the base and convert it to id : (true)(false) on each brand
{"content":{"brands":1},"brands":[{"id":"1","name":"brand 1","description":"description","icon":"icon","url":"example.com"},{"id":"2","name":"brand2","description":"description","icon":"icon","url":"example.com"}]}
Can you help me?
Regards
After you are done building the brands, loop on the categories, searching brands for the existing id match. If it matches, then adjust a true false value for the categories. Then when the categories are completed, append them to every brand in a final loop.
$cleancats = [];
foreach ($categories as $cat) {
$result = false;
foreach($brands as $brand) {
if ($cat['id'] == $brand['id']) {
$result = true; break;
}
}
$cleancats[ $cat['id'] ] = $result;
}
array_walk ($brands,function(&$brand) use ($cleancats) {
$brand['categories'] = $cleancats;
});
(note put this after your for ($i = 1, $j = 0; $i < $total; $i++) loop ends)
That should get the categories to every brand in brands, as you would like.
If you need the categories to be a LITERAL "true" and "false" then adjust this one line above:
$cleancats[ $cat['id'] ] = ($result?'true':'false');

PHP (codeigniter) - How to check if the next two rows have value?

I wanted to check if the next TWO rows or ID is not NULL.
because if there is no succeeding TWO rows or ID then the income remains zero.
foreach ($data as $row)
{
if(($row->id + 2) != NULL) //I don't know what is the correct statement here
{
echo "<tr>";
echo "<td>".$row->id."</td>";
echo "<td>".$row->username."</td>";
echo "<td>"."650.00"."</td>";
echo "<td>".$row->remarks."</td>";
echo "<tr>";
}
else
{
echo "<tr>";
echo "<td>".$row->id."</td>";
echo "<td>".$row->username."</td>";
echo "<td>".$row->income."</td>";
echo "<td>".$row->remarks."</td>";
echo "<tr>";
}
}
Here is the table I want to achieve.
==================================
|ID | Username | Income | Remarks|
| 2 | user1 | 650.00 | |
| 3 | user2 | 650.00 | |
| 4 | user3 | 0.00 | |
| 5 | user4 | 0.00 | |
==================================
If I add a username then the next output will be this:
==================================
|ID | Username | Income | Remarks|
| 2 | user1 | 650.00 | |
| 3 | user2 | 650.00 | |
| 4 | user3 | 650.00 | |
| 5 | user4 | 0.00 | |
| 6 | user5 | 0.00 | |
==================================
You need to change your foreach to get the index.
foreach ($data as $index => $row)
Then you can address all rows relative to your current row with:
$row_two_ahead = $data[$index + 2];
you should check however if that row exists before you try to use it or you will get index out of range exceptions:
if (isset($data[$index + 2])) {
}
I solved the problem...
this is the code from my controller:
public function addUsername()
{
$data['id'] = NULL;
$data['username'] = $this->input->post('username');
$data['reward'] = 0.00;
$data['remarks'] = ' ';
$this->Matrix_model->addUsername($data);
$last = $this->Matrix_model->getLast();
$index = $last - 2; //I minus the last index with two
$this->Matrix_model->updateIncome($index); //and updated the income of that index
redirect('http://localhost/matrix/index.php/matrix');
}
and this is the code from my model:
public function addUsername($data)
{
$this->db->insert("income", $data);
}
public function getLast()
{
return $this->db->insert_id(); //this is the method to access the last id inserted
}
public function updateIncome($id)
{
$this->db->set("reward", 650);
$this->db->where("id", $id);
$this->db->update("income");
}
thank you and I'm sorry if other programmers didn't understand my questions

If Statement (PHP)

I need If Statement (php) to :
if (Modem = ModemNotReceived) and (CheckModem = Done)
Total + 50
And
if (Modem = ModemReceived) and (CheckModem = Done)
Total - 50
How i can do that in one if statement?
My Table :
| ID | Modem | CheckModem | Total
------------------------------------------------
| 1 | ModemReceived | Done | 120
------------------------------------------------
| 2 | ModemNotReceived | Null | 90
------------------------------------------------
| 3 | ModemReceived | Null | 100
If I understand what you're saying correctly, this code is what you mean:
<?php
if ($Modem == 'ModemNotReceived' && $CheckModem == 'Done') {
$Total += 50;
} else if ($Modem == 'ModemReceived') && $CheckModem == 'Done' {
$Total -= 50;
}
?>

PHP MySQL code optimize

Is there any MySQL function that will optimize this code? A child ID getting all parent ID
function get_parents() {
$ids = array();
while($id) :
$query = "SELECT placement_id FROM referrals WHERE user_id = $id";
$query = $this->db->query($query);
$result = $query->row();
if(!isset($result->placement_id)) :
break;
elseif(isset($result->placement_id) && $result->placement_id == 2) :
break;
endif;
$id = $result->placement_id;
array_push($ids, $id);
if($result) :
continue;
endif;
break;
endwhile;
return $ids;
}
The code above will return all parent ID of given user_id, this will stop if nothing is found. I found this code too slow and heavy load.
My Table
relations table
| id | user_id | placement_id |
| 1 | 2 | NULL |
| 2 | 3 | 2 |
| 3 | 4 | 2 |
| 4 | 5 | 3 |
| 5 | 6 | 4 |
| 6 | 7 | 3 |
| 7 | 8 | 3 |
| 8 | 9 | 3 |
| 9 | 10 | 6 |
| 10 | 11 | 5 |
| 11 | 12 | 6 |
| 12 | 13 | 4 |
| 13 | 14 | 3 |
| 14 | 15 | 9 |
| 15 | 16 | 10 |
user_id is the child and parent is placement_id
You can rewrite you code as:
function get_parents() {
$ids = array();
while($id){
$query = "SELECT placement_id FROM referrals WHERE user_id = $id";
$query = $this->db->query($query);
$result = $query->row();
if(isset($result->placement_id) && $result->placement_id !== 2)
{
$id = $result->placement_id;
array_push($ids, $id);
}
}
return $ids;
}
It excludes some additional function calls such continue,break etc. Also, Make sure you have INT as type of user_id with indexing on this column.
I would personally do something like this:
<?php
define('MAX_NEST_DEPTH', 15);
function get_parent($child_id) {
$child_id = (int) $child_id;
$parents = array();
$counter = 0;
do {
$sql = "SELECT placement_id
FROM referrals
WHERE user_id = {$child_id}";
$query = $this->db->query($query);
$result = $query->row();
$child_id = (int) $result->placement_id;
$parent[] = $child_id;
$counter++;
}
while ($child_id != 0 || $counter == MAX_NEST_DEPTH);
return $parents;
}
You wont get around the query in a loop here, mysql does not support n-level-nested SELECT, otherwise we could just do it in one go.

foreach for groups and subgroups in php

i have table in database:
Group:
| id | Category | title |
| 1 | 1 | group1 |
| 2 | 2 | group2 |
| 3 | 1 | group3 |
| 4 | 3 | group4 |
| 5 | 2 | group5 |
| 6 | 1 | group6 |
News:
| id | Group | title | body |
| 1 | 3 | title1 | body1 |
| 2 | 2 | title2 | body2 |
| 3 | 1 | title3 | body3 |
| 4 | 4 | title4 | body4 |
| 5 | 1 | title5 | body5 |
| 6 | 5 | title6 | body6 |
| 7 | 3 | title7 | body7 |
| 8 | 2 | title8 | body8 |
| 9 | 1 | title9 | body9 |
| 10 | 6 | title10| body10 |
| 11 | 1 | title11| body11 |
| 12 | 5 | title12| body12 |
how can i show this as:
-GROUP1, GROUP3 and GROUP6
//GROUP1 (category1)
--title3
--title5
--title9
//GROUP3 (category1)
--title1
--title7
//GROUP6 (category1)
--title10
-GROUP2 and GROUP5
//GROUP2 (category2)
--title2
--title8
//GROUP5 (category2)
--title6
--titl12
-GROUP4
//GROUP4 (category3)
--title4
i will make this in foreach. thanks for help!
Your exact requested output makes this complicated.
$sql = 'SELECT n.title, n.Group AS group_id, g.Category AS cat_id
FROM News AS n
JOIN Group AS g ON g.id = group_id
ORDER BY cat_id, group_id, n.id';
$result = mysql_query($query);
$categories = array();
while ($row = mysql_fetch_assoc($result)) {
$catID = $row['cat_id'];
$groupID = $row['group_id'];
$title = $row['title'];
$categories[$catID]['groups'][$groupID]['titles'][] = $title;
}
foreach ($categories as $catID => $groups) {
$catGroups = '-GROUP'.implode(', GROUP',array_keys($groups)).PHP_EOL;
$lastComma = strrpos($catGroups,',');
if ($lastComma !== false) {
$catGroups = substr($catGroups,0,$lastComma-1).
' AND ' .substr($catGroups,$lastComma+1);
}
echo $catGroups;
foreach ($groups as $groupID => $titles) {
echo "//GROUP$groupID (category$catID)".PHP_EOL;
foreach ($groups as $group => $titles) {
echo '--'.$title.PHP_EOL;
}
}
}
If you didn't need such fancy output, this would be much simpler.
$sql = 'SELECT n.title, n.Group AS group_id, g.Category AS cat_id
FROM News AS n
JOIN Group AS g ON g.id = group_id
ORDER BY cat_id, group_id, n.id';
$result = mysql_query($query);
$lastCatID = null;
$lastGroupID = null;
while ($row = mysql_fetch_assoc($result)) {
$catID = $row['cat_id'];
$groupID = $row['group_id'];
$title = $row['title'];
if ($catID !== $lastCatID){
echo "*** CATEGORY $catID\n";
$lastCatID = $catID;
}
if ($groupID !== $lastGroupID){
echo "GROUP $groupID\n";
$lastGroupID = $groupID;
}
echo "-- $title\n";
}
You told, you have your values in the database. So you have to get them first, e.g. with the following database query:
SELECT
g.`title` AS `group_title`
, n.`title` AS `news_title`
FROM
`Group` AS g
INNER JOIN
`News` AS n
ON
g.`id` = n.`Group`
ORDER BY
g.`Category`
, n.`Group`
, n.`title`
Store the data in an array. Now you can use a foreach loop to iterate over the array.
===
Here my update:
First fill the array while reading from the database (example query see above).
<?php
$data = array();
$res = mysql_query('SELECT ...');
while (($row = mysql_fetch_assoc($res)) !== false) {
$data[$row['group_title']][] = $row['news_title'];
}
?>
Then write the array to the screen:
<?php
foreach ($data as $group_title => $groups) {
echo $group_title . "\n";
foreach ($groups as $news) {
echo "\t" . $news . "\n";
}
}
?>

Categories