Displaying the sum of a foreach loop - php

I have a table like this: id | item_name | price
I have a loop that displays all items with the grand total at the bottom.
$total_price = 0;
foreach($items as $item)
{
echo $item->item_name;
echo $item->price;
$total_price += $item->price;
}
echo $total_price;
However, what I need is to display the $total_price at the TOP of the page, before I loop through all the items.
Is it better to loop through the foreach again at the top of the page to calculate the total price, or should I be making a separate database call that only returns the total price?

It's simple and fast decision
$total_price = 0;
$print = '';
foreach($items as $item)
{
$print .= $item->item_name;
$print .= $item->price;
$total_price += $item->price;
}
echo $total_price;
echo $print;
If you can get sum from SQL base it will be more best solution. In MySQL use function SUM()
Example:
SELECT SUM(price) AS total FROM ...

This is one of the reasons why you should never mix php code and direct output. I would suggest you look into one of the template engines for php.
Unless you are writing php-cli do all the operations before you start to output. This will increase the flexibility of your code a lot.
Smarty is one of my favourite tempelate engines, easy to setup and with powerfull features, but that's my opinion.

Maybe you need use MySQL query like this:
SELECT SUM(price) FROM your_table

Related

Sum mysql array in PHP

I need sum up quantity items. I have a database query, I print values:
while ($row = mysqli_fetch_array($lista)) {
echo $row['przedmiot'].":".$row['ilosc'].'<br>';
}
then I get this result:
item1:1
item1:3
item2:1
item1:3
item2:5
I need to add these values, I would like to get this result:
item1:7
item2:6
#Sascha's answer will work, but I'd suggest a different approach - instead of querying all these rows, transferring them from the database to your application and then having to loop over them in the code, let the database do the heavy lifting for you:
SELECT przedmiot, SUM(ilosc) AS ilosc
FROM mytable
GROUP BY przedmiot
This should help:
$result=[];
while ($row = mysqli_fetch_array($lista)) {
echo $row['przedmiot'].":".$row['ilosc'].'<br>';
if (!array_key_exists ($result, $row['przedmiot'])) {
$result[$row['przedmiot']] = $row['ilosc'];
} else {
$result[$row['przedmiot']] += $row['ilosc'];
}
}

PHP loop sum from database

$st = $this->db->prepare("SELECT * FROM invoices WHERE group_id=?");
$st->execute(array($id));
if($st->rowCount() >= 1){
foreach ($st as $row) {
$counter = $row["paymentAmount"];
$start = 1;
for($start; $start < $st->rowCount(); $start++) {
$counter = $counter + $row["paymentAmount"];
}
}
It actually print out $row["paymentAmount"] + $row["paymentAmount"] and so on, depending on how many $row["paymentAmount"] there is. But the problem is that the last output from $row["paymentAmount"] is 2500.
There is:
10000
10000
2500
And the result is: 7500
I want it to be: 22500
And if the last result is 3000 it shall be 23000. So what I simply need is this code to take every row from the database, just not the latest one.
Edit: I want it outside of the SQL query
You don't need PHP logic for something like this. The functionality is built right into SQL.
SELECT SUM(paymentAmount) FROM invoices WHERE group_id=?
You should let your database handle the sum unless you have a legitimate reason why it needs to be handled in PHP. The database is more efficient with this type of operation and you avoid a loop in PHP.
SELECT SUM(paymentAmount) AS TotalPaymentAmount FROM invoices WHERE group_id = ?
You can then change your PHP to return just one row:
$row = $st->fetch();
echo $row["TotalPaymentAmount"];
If you need to do this calculation outside of SQL, just change your loop:
if($st->rowCount() >= 1){
//init the counter to 0 before you loop through your rows
$counter = 0;
//the foreach will iterate over your result set and add the paymentAmount to $counter.
foreach ($st as $row) {
$counter += $row["paymentAmount"];
}
//echo results outside of the loop
echo $counter;
}
If you need to code this outside SQL on purpose (e.g. because you need to do further processing for each row), then I'd code this as follows:
if ($st->rowCount() >= 1) {
$counter = 0;
foreach ($st as $row) {
$counter += $row["paymentAmount"];
}
}

How to make the summ (total) with php if there is more than one price?

I'll make it simple, let's say i have a shopping cart, and three different prices:
$price
$specialprice
$salesprice
of course there are product quantities.
The first step of math is:
<?php
$price_regular = $price * $quantity
$price_special = $specialprice * $quantity
$price_sales = $salesprice * $quantity
?>
So let me make a simple example, after adding 3 products in cart:
Product A - 30$ ($price)
Product B - 25$ ($specialprice) (old price was 30$)
Product C - 22$ ($salesprice) (old product was 35$)
The summ shoud be 77$.
This is the result i want to get from my code.
But HOW?
I tried doing smthing like:
<?php
$totalprice = $totalprice + $price_regular;
?>
but it only gives me the summ of REGULAR price. I need the code to calculate exactlly as in my simple example with product A - B - C
This is the real code from my file:
$totalprice = 0;
$totalarticles = count($itemsonpage);
for ($i=0;$i<=(count($itemsonpage) - 1);$i++){
$productslist[$i]['id'] = $itemsonpage[$i]['productid'];
$products->ShowByID($itemsonpage[$i]['productid']);
$productslist[$i]['code'] = $products->code;
$products->ShowLangDataByID($products->id,$chooselang);
$productslist[$i]['name'] = $products->name;
$productslist[$i]['quantity'] = $itemsonpage[$i]['quantity'];
$productslist[$i]['price'] = $itemsonpage[$i]['price'];
$productslist[$i]['specialprice'] = $products->specialprice;
$productslist[$i]['salesprice'] = $products->salesprice;
$productslist[$i]['allprice'] = $products->price * $productslist[$i]['quantity'];
$productslist[$i]['allprice2'] = $products->specialprice * $productslist[$i]['quantity'];
$productslist[$i]['allprice3'] = $products->salesprice * $productslist[$i]['quantity'];
$totalprice = $totalprice + $productslist[$i]['allprice'];
<?php
$totalprice += $price_regular;
$totalprice += $price_special;
$totalprice += $price_sales;
echo $totalprice;
?>
Why can't you calculate it like this?
<?php
$totalprice = $price_sales + $price_special + $price_regular;
?>
Since you are adding just the $price_regular you are only getting that in $totalprice. You need to try something like this, adding up all the 3 prices,
$totalprice = $price_regular + $price_special + $price_sales;
I imagine in your cart there are several products, and you don't know how many. You should read up about PHP arrays and about PHP loops.
Then, to use an array and a loop to carry out your sum, you would use an operation like this:
<?php
$totalprice = 0;
$prices=array(30,25,22);
foreach ($prices as $each)
{
$totalprice += ;
}
echo $totalprice."<br />";
?>
From your question I understand that you need to add 3 numbers, all the answers above tell you how to add 3 numbers.
I figure you actually asked the wrong questions so I will give you a wrong answer maybe it is what you want.
You have the following db structure
table product (id, name, price_sales, price_special, price_regular)
price_sales and price_special can be 0, that shows that that product is not on sale or on special.
TO get the total you have to perform a select on each product from the db based on the id and you get an object with the columns as properties. Your code should be something like this.
$products = function_that_gets_the_products_from_the_db();
foreach($products as $product) {
$total_cart += $product->price_sales ? $product->price_sales : ($product->price_special ? $product->price_special : $product->price_regular)
}
This code checks if the product is on sale, if it is then it uses that price, if it is not then it checks if it is on special, if it is then it uses that price otherwise it uses the normal price.

PHP - Nested List Broken into Even Columns (fix and updates)

I have a follow-up to a previous thread/question that I hope can be solved by relatively small updates to this existing code. In the other thread/question, I pretty much solved a need for a nested unordered list. I needed the nested unordered list to be broken up into columns based on the number of topics.
For example, if a database query resulted in 6 topics and a user specified 2 columns for the layout, each column would have 3 topics (and the related news items below it).
For example, if a database query resulted in 24 topics and a user specified 4 columns for the layout, each column would have 6 topics (and the related news items below it).
The previous question is called PHP - Simple Nested Unordered List (UL) Array.
The provided solution works pretty well, but it doesn't always divide
correctly. For example, when $columns = 4, it only divides the
columns into 3 groups. The code is below.
Another issue that I'd like to solve was brought to my attention by
the gentleman who answered the question. Rather than putting
everything into memory, and then iterating a second time to print it
out, I would like to run two queries: one to find the number of
unique TopicNames and one to find the number of total items in the
list.
One last thing I'd like to solve is to have a duplicate set of
code with an update that breaks the nested unordered list into columns
based on the number of news items (rather than categories). So, this
would probably involve just swapping a few variables for this second
set of code.
So, I was hoping to solve three issues:
1.) Fix the division problem when relying on the number of categories (unordered list broken up into columns based on number of topics)
2.) Reshape the PHP code to run two queries: one to find the number of unique TopicNames and one to find the number of total items in the list
3.) Create a duplicate set of PHP code that works to rely on the number of news items rather than the categories (unordered list broken up into columns based on number of news items)
Could anyone provide an update or point me in the right direction? Much appreciated!
$columns = // user specified;
$result = mysql_query("SELECT * FROM News");
$num_articles = 0;
// $dataset will contain array( 'Topic1' => array('News 1', 'News2'), ... )
$dataset = array();
while($row = mysql_fetch_array($result)) {
if (!$row['TopicID']) {
$row['TopicName'] = 'Sort Me';
}
$dataset[$row['TopicName']][] = $row['NewsID'];
$num_articles++;
}
$num_topics = count($dataset);
// naive topics to column allocation
$topics_per_column = ceil($num_topics / $columns);
$i = 0; // keeps track of number of topics printed
$c = 1; // keeps track of columns printed
foreach($dataset as $topic => $items){
if($i % $topics_per_columnn == 0){
if($i > 0){
echo '</ul></div>';
}
echo '<div class="Columns' . $columns . 'Group' . $c . '"><ul>';
$c++;
}
echo '<li>' . $topic . '</li>';
// this lists the articles under this topic
echo '<ul>';
foreach($items as $article){
echo '<li>' . $article . '</li>';
}
echo '</ul>';
$i++;
}
if($i > 0){
// saw at least one topic, need to close the list.
echo '</ul></div>';
}
UPDATE 12/19/2011: Separating Data Handling from Output Logic (for the "The X topics per column variant"):
Hi Hakre: I've sketched out the structure of my output, but am struggling with weaving the two new functions with the old data handling. Should the code below work?
/* Data Handling */
$columns = // user specified;
$result = mysql_query("SELECT * FROM News LEFT JOIN Topics on Topics.TopicID = New.FK_TopicID WHERE News.FK_UserID = $_SESSION[user_id] ORDER BY TopicSort, TopicName ASC, TopicSort, NewsTitle");
$num_articles = 0;
// $dataset will contain array( 'Topic1' => array('News 1', 'News2'), ... )
$dataset = array();
while($row = mysql_fetch_array($result)) {
if (!$row['TopicID']) {
$row['TopicName'] = 'Sort Me';
}
$dataset[$row['TopicName']][] = $row['NewsID'];
$num_articles++;
}
/* Output Logic */
function render_list($title, array $entries)
{
echo '<ul><li>', $title, '<ul>';
foreach($entries as $entry)
{
echo '<li>', $entry['NewsID'], '</li>';
}
echo '</ul></li></ul>;
}
function render_column(array $topics)
{
echo '<div class="column">';
foreach($topics as $topic)
{
render_list($topic['title'], $topic['entries']);
}
echo '</div>';
}
You have not shown in your both questions what the database table is, so I can not specifically answer it, but will outline my suggestion.
You can make use of aggregation functions in mysql to obtain your news entries ordered and grouped by topics incl. their count. You can do two queries to obtain counts first, that depends a bit how you'd like to deal with your data.
In any case, using the mysql_... functions, all data you selected from the database will be in memory (even twice due to internals). So having another array as in your previous question should not hurt much thanks to copy on write optimization in PHP. Only a small overhead effectively.
Next to that before you take care of the actual output, you should get your data in order so that you don't need to mix data handling and output logic. Mixing does make things more complicated hence harder to solve. For example if you put your output into simple functions, this gets more easy:
function render_list($title, array $entries)
{
echo '<ul><li>', $title, '<ul>';
foreach($entries as $entry)
{
echo '<li>', $entry['NewsID'], '</li>';
}
echo '</ul></li></ul>;
}
function render_column(array $topics)
{
echo '<div class="column">';
foreach($topics as $topic)
{
render_list($topic['title'], $topic['entries']);
}
echo '</div>';
}
This already solves your output problem, so we don't need to care about it any longer. We just need to care about what to feed into these functions as parameters.
The X topics per column variant:
With this variant the data should be an array with one topic per value, like you did with the previous question. I would say it's already solved. Don't know which concrete problem you have with the number of columns, the calculation looks good, so I skip that until you provide concrete information about it. "Does not work" does not qualify.
The X news items per column variant:
This is more interesting. An easy move here is to continue the previous topic with the next column by adding the topic title again. Something like:
Topic A Topic A Topic B
- A-1 - A-5 - B-4
- A-2 Topic B - B-5
- A-3 - B-1 - B-6
- A-4 - B-2
- B-3
To achieve this you need to process your data a bit differently, namely by item (news) count.
Let's say you managed to retrieve the data grouped (and therefore sorted) from your database:
SELECT TopicName, NewsID FROM news GROUP BY 1;
You can then just iterate over all returned rows and create your columns, finally output them (already solved):
$itemsPerColumn = 4;
// get columns
$topics = array();
$items = 0;
$lastTopic = NULL;
foreach ($rows as $row)
{
if ($lastTopic != $row['TopicName'])
{
$topic = array('title' => $row['TopicName']);
$topics[] = &$topic;
}
$topic['entries'][] = $row;
$items++;
if ($items === $itemsPerColumn)
{
$columns[] = $topics;
$topics = array();
$lastTopic = NULL;
}
}
// output
foreach($columns as $column)
{
render_column($column);
}
So this is actually comparable to the previous answer, but this time you don't need to re-arrange the array to obtain the news ordered by their topic because the database query does this already (you could do that for the previous answer as well).
Then again it's the same: Iteration over the returned result-set and bringing the data into a structure that you can output. Input, Processing, Output. It's always the same.
Hope this is helpful.

grand total sum in php

this may sound lame but i am stuck up with summing up the values retrieved from mysql.
i want to sum up the grand total of the sales invoice items that is retrieved from mysql database.
following is the code for sub total for each line which is fine.
while($row = mysql_fetch_array($qry)){
echo $row['b'] * $row['c'];
}
'b' is the quantity and 'c' is the price.all these values are retrieved from mysql and the no of rows is variable and all this is inside the while loop.
Now outside of the while loop, the last row, i want the grand total. can somebody point me in the right direction. i tried
echo SUM($row['b'] * $row['c']);
but this doesn't work and gives an error. i am sure i am doing it wrongly.
$total = 0;
while($row = mysql_fetch_array($qry))
{
echo $row['b'] * $row['c'];
$total += ($row['b'] * $row['c']);
}
// at the end, $total = grand total
Why not use SQL for things SQL does best?
SELECT SUM(b*c)
FROM table
Simple as that.

Categories