Issue with number_format price - php

In my database I have values:
422 = 4,22 EUR
4222 = 42,22 EUR
42222 = 422,22 EUR
I try number_format
<?php
$template = 'The price of the product is {price}.';
$row['price'] = 4222;
$template = str_replace('{price}', number_format($row['price'], 2, '.', ''), $template);
echo $template;
But I get output:
https://3v4l.org/OtWRs
The price of the product is 4222.00.

Related

PHP for loop with array and array slice functions

As part of an expense data analyze, I am trying to find out top 3 expense categories for each month.Right now I have 3 months data : Array $month0,$month1,$month3.
Right now I am using below code and its working fine
$month0 = array("Bank"=>$Bank[0], "CreditCard"=>$CreditCard[0], "Loan"=>$Loan[0],"Household"=>$Household[0],"Utilities"=>$Utilities[0]);
$month1 = array("Bank"=>$Bank[1], "CreditCard"=>$CreditCard[1], "Loan"=>$Loan[1],"Household"=>$Household[1],"Utilities"=>$Utilities[1]);
$month2 = array("Bank"=>$Bank[2], "CreditCard"=>$CreditCard[2], "Loan"=>$Loan[2],"Household"=>$Household[2],"Utilities"=>$Utilities[2]);
arsort($month0 );
arsort($month1 );
arsort($month2 );
$top3month0 = array_slice($month0, 0, 3);
$top3month1 = array_slice($month1, 0, 3);
$top3month2 = array_slice($month2, 0, 3);
foreach ($top3month0 as $category => $amount){
$cat_top3month0[] = $category;
$amt_top3month0[] = $amount;
}
foreach ($top3month1 as $category => $amount){
$cat_top3month1[] = $category;
$amt_top3month1[] = $amount;
}
foreach ($top3month2 as $category => $amount){
$cat_top3month2[] = $category;
$amt_top3month2[] = $amount;
}
//For Month0
echo "Top 1 category is ".$cat_top3month0[0]." and amount: ".$amt_top3month0[0];
echo "Top 2 category is ".$cat_top3month0[1]." and amount: ".$amt_top3month0[1];
echo "Top 3 category is ".$cat_top3month0[2]." and amount: ".$amt_top3month0[2];
//For Month1
echo "Top 1 category is ".$cat_top3month1[0]." and amount: ".$amt_top3month1[0];
echo "Top 2 category is ".$cat_top3month1[1]." and amount: ".$amt_top3month1[1];
echo "Top 3 category is ".$cat_top3month1[2]." and amount: ".$amt_top3month1[2];
//For Month3
echo "Top 1 category is ".$cat_top3month2[0]." and amount: ".$amt_top3month2[0];
echo "Top 2 category is ".$cat_top3month2[1]." and amount: ".$amt_top3month2[1];
echo "Top 3 category is ".$cat_top3month2[2]." and amount: ".$amt_top3month2[2];
I am trying to use for loop here to reduce the length of the code. I changed above code like below using for loop
for ($i = 0; $i<3; $i++){
$month[i] = array("Bank"=>$Bank[i], "CreditCard"=>$CreditCard[i], "Loan"=>$Loan[i],"Household"=>$Household[i],"Utilities"=>$Utilities[i]);
arsort($month[i] );
$top3month[i] = array_slice($month[i], 0, 3);
foreach ($top3month[i] as $category => $amount){
$cat_top3month[i][] = $category;
$amt_top3month[i][] = $amount;
}
}
//For Month0
/echo "Top 1 category is ".$cat_top3month0[0]." and amount: ".$amt_top3month0[0];
/echo "Top 2 category is ".$cat_top3month0[1]." and amount: ".$amt_top3month0[1];
/echo "Top 3 category is ".$cat_top3month0[2]." and amount: ".$amt_top3month0[2];
//For Month1
echo "Top 1 category is ".$cat_top3month1[0]." and amount: ".$amt_top3month1[0];
echo "Top 2 category is ".$cat_top3month1[1]." and amount: ".$amt_top3month1[1];
echo "Top 3 category is ".$cat_top3month1[2]." and amount: ".$amt_top3month1[2];
//For Month3
echo "Top 1 category is ".$cat_top3month2[0]." and amount: ".$amt_top3month2[0];
echo "Top 2 category is ".$cat_top3month2[1]." and amount: ".$amt_top3month2[1];
echo "Top 3 category is ".$cat_top3month2[2]." and amount: ".$amt_top3month2[2];
But above code is not working. When looking at the debug log I see below error
PHP Warning: Use of undefined constant i - assumed 'i' (this will throw an Error in a future version of PHP)
against line
$month[i] = array("Bank"=>$Bank[i], "CreditCard"=>$CreditCard[i], "Loan"=>$Loan[i],"Household"=>$Household[i],"Utilities"=>$Utilities[i]);
I am new to PHP and still learning. Can someone please tell me the issue with code ? or suggest a better approach to this ?
Update:
Updated the code to correct i to $i
for ($i = 0; $i<3; $i++){
$month[$i] = array("Bank"=>$Bank[$i], "CreditCard"=>$CreditCard[$i], "Loan"=>$Loan[$i],"Household"=>$Household[$i],"Utilities"=>$Utilities[$i]);
arsort($month[$i] );
$top3month[$i] = array_slice($month[$i], 0, 3);
foreach ($top3month[$i] as $category => $amount){
$cat_top3month[$i][] = $category;
$amt_top3month[$i][] = $amount;
}
}
//For Month0
echo "Top 1 category is ".$cat_top3month0[0]." and amount: ".$amt_top3month0[0];
echo "Top 2 category is ".$cat_top3month0[1]." and amount: ".$amt_top3month0[1];
echo "Top 3 category is ".$cat_top3month0[2]." and amount: ".$amt_top3month0[2];
//For Month1
echo "Top 1 category is ".$cat_top3month1[0]." and amount: ".$amt_top3month1[0];
echo "Top 2 category is ".$cat_top3month1[1]." and amount: ".$amt_top3month1[1];
echo "Top 3 category is ".$cat_top3month1[2]." and amount: ".$amt_top3month1[2];
//For Month3
echo "Top 1 category is ".$cat_top3month2[0]." and amount: ".$amt_top3month2[0];
echo "Top 2 category is ".$cat_top3month2[1]." and amount: ".$amt_top3month2[1];
echo "Top 3 category is ".$cat_top3month2[2]." and amount: ".$amt_top3month2[2];
Now I have below errors:
PHP Notice: Array to string conversion in
against line :
$month[$i] = array("Bank"=>$Bank[$i], "CreditCard"=>$CreditCard[$i], "Loan"=>$Loan[$i],"Household"=>$Household[$i],"Utilities"=>$Utilities[$i]);
and
PHP Fatal error: Uncaught Error: Only variables can be passed by reference in
against arsort($month[$i] );

Best practice to sum and format numbers to dollar values with 2 decimal points?

Here's the code I came up with, I want to:
sum price + shipping to a total
always display formatted numbers with two decimal points
have a dollar sign at the start for all three values
display an alternative "free shipping" if the shipping value is zero.
PHP:
$price0 = "356";
$ship0 = "9.9";
$tprice0 = $price0 + $ship0;
$price1 = number_format((float)$price0, 2, '.', '');
$ship1 = number_format((float)$ship0, 2, '.', '');
$tprice1 = number_format((float)$tprice0, 2, '.', '');
if($ship0 == 0) { $shipping1 = '<span class="free">Free Shipping</span>'; } else { $shipping1 = "$$ship1"; }
HTML:
Price: $<?php echo $price1; ?>
Shipping: <?php echo $shipping1; ?>
Total: $<?php echo $tprice?>
Is this the best practice? (e.g, I'm using a double dollar sign), and is there a way to make the code cleaner / shorter?
EDIT:
note that I want to have this practice for several products in the same page, so is there a way to make it shorter?
$price0b = "223";
$ship0b = "5.5";
$tprice0b = $price0b + $ship0b;
$price1b = number_format((float)$price0b, 2, '.', '');
$ship1b = number_format((float)$ship0b, 2, '.', '');
$tprice1b = number_format((float)$tprice0b, 2, '.', '');
if($ship0b == 0) { $shipping1b = '<span class="free">Free Shipping</span>'; } else { $shipping1b = "$$ship1b"; }
EDIT2:
I'm getting a class not found error with this code:
<?php
$price = "356";
$shipping = "0";
$total_price = $price0 + $ship0;
$oNumberFormatter = new NumberFormatter('en_US', NumberFormatter::PATTERN_DECIMAL, '¤ #,##0.00');
?>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
Price: <?= $oNumberFormatter->format( (float) $price ); ?>
Shipping: <?= !$ship0b ? "<span class=\"free\">Free Shipping</span>" : $oNumberFormatter->format( (float) $shipping ); ?>
Total: <?= $oNumberFormatter->format( (float) $total_price ); ?>
To format a number to en_US currency format you can create a NumberFormatter object like this:
$oNumberFormatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
In this instance prices will be formatted up to normal rules for the given locale; for instance $9.95 for 'en_US` or € 9,95 for 'nl_NL'
If you want a specific ICU Decimal format you could use:
$oNumberFormatter = new NumberFormatter('en_US', NumberFormatter::PATTERN_DECIMAL, '¤ #,##0.00');
The currency symbol (¤) in the format will automatically be converted, when echoed out, to the correct symbol specified by the locale string; so for 'en_US' the dollar symbol ($) will be used - for 'nl_NL' the Euro (€) and so on.
Either way, in your product display loop, to display the correctly formatted product price, you need only (assuming your product price here is $price) use:
<?= $oNumberFormatter->format( (float) $price); ?>
... and for your free shipping insert:
<?= !$shipping ? "<span class=\"free\">Free Shipping</span>" : $oNumberFormatter->format( (float) $shipping ); ?>
Full details on the NumberFormatter class are at: http://php.net/manual/en/class.numberformatter.php
Just an edit to answer the question in the comments
Ok, thanks. can you explain what you did with the shipping part? I
didn't understand how that format is working. also, how to insert a
dollar sign if for the time being I will use Free Shipping" : number_format((float)$shipping,
2, '.', ''); ?> ?
<?= is shorthand for <?php echo
I'm just using a ternary operator: http://php.net/manual/en/language.operators.comparison.php (scroll down the page a little) - it's just a sort of shorthand for directly assigning a value based on a sort of if (?) else (:) notation:
!$shipping equates to $shipping == false which equates to $shipping == 0 since PHP is loosely typed, so:
<?= !$shipping ? "<span class=\"free\">Free Shipping</span>" : $oNumberFormatter->format( (float) $shipping ); ?>
... is equivalent to ...
<?php
if($shipping == 0) {
echo "<span class=\"free\">Free Shipping</span>";
}
else {
echo $oNumberFormatter->format( (float) $shipping );
}
?>
And for literally outputting a $ string... just use a non-interpolated string literal. PHP has 2 types of string literal (well, 4 with heredoc syntaxes) but essentially an interpolated string is enclosed in double quotes and will parse variables.
<?php
$sWord = "BADGERS";
echo "I like $sWord";
?>
Results in I like BADGERS
Whereas a non-interpolated string (enclosed in apostrophes) will treat $ literally - it won't interpolate variables:
<?php
$sWord = "BADGERS";
echo 'I like $sWord';
?>
Results in I like $sWord literally.
So you can echo out your currency value, with a prefixed dollar sign, like so:
echo '$' . number_format( (float) $shipping, 2, '.', '');
i will most likely do this
PHP
$price = "356";
$ship = "9.9";
$tprice = $price + $ship;
HTML
Price: $<?php echo setdecimalPoint($price); ?>
<?php if($ship == 0) { ?>
<span class="free">Free Shipping</span>
<?php }else{ ?>
Shipping: <?php echo setdecimalPoint($shipping); ?>
<?php } ?>
Total: $<?php echo setdecimalPoint($tprice)?>

Displaying currency values greater than 1000

I'm trying to modify a pseudo-shopping cart (it's array based storing values in user meta and not database) PHP file that wrongly displays currency > 1000 as 0.01
Here's the block I want to change:
public function get_cart_value()
{
$cart = $this->cart;
$prices = array();
$cart = apply_filters('ss_mod_cart_value', $cart);
foreach ($cart['products'] as $product)
{
array_push( $prices, array('price'=>trim($product['price']), 'discount' => trim($product['discount'] )));
}
$total = 0;
foreach($prices as $price)
{
$price = $this->calc_discount($price['price'], $price['discount']);
$price = str_replace('.', '', $price['final_price']);
$total += $price;
}
$total = number_format($total/100, 2);
return $total;
}
The cart button it works on will correctly display the total values of items less than 4 digits, for example:
300 + 500 = 800
but
300 + 500 + 1000 = 800.01 instead of 1,800
I've been trying to change number_format() to make it work but cannot find a solution.
I think by this line
$price = str_replace('.', '', $price['final_price']);
300+500+ "1000";
your numbers like 1,000 are converted to a string and then your total becomes 801.
you have to convert to float in proper way as suggested in this
PHP: unformat money

PHP: How to display decimal numbers in an array?

This is a tricky question to ask. A friend of mine seeks help, and I am not really into the project so it is difficult to describe the problem.
He has a shopping cart written in PHP, and in that shopping cart he wants all the product prices to be counted into a total price.
The problem is, all the prices are in a MySQL database. Displaying the prices (with decimals) is not a problem but, when these prices are counted and put in a variable, the decimals are not shown.
How can we solve this problem?
I will show you the code that he uses for displaying the prices in the shopping cart:
// Show cart
foreach($cart as $products) {
// Split
/*
$product[x] -->
x == 0 -> product id
x == 1 -> hoeveelheid
*/
$product = explode(",",$products);
// Get product info
$sql = "SELECT product_nummer, productnaam, verkoopprijs
FROM product
WHERE product_nummer = ".$product[0]; // Komt uit de sessie
$query = mysql_query($sql) or die (mysql_error()."<br>in file ".__FILE__." on line ".__LINE__);
$pro_cart = mysql_fetch_object($query);
$i++;
$price = $pro_cart->verkoopprijs; // variable price aanmaken zodat er opgeteld wordt
echo "<tr>\n";
echo " <td>"." • ".$pro_cart->productnaam."</td>\n"; // naam
echo " <td><input type=\"hidden\" name=\"productnummer_".$i."\" value=\"".$product[0]."\" />\n"; // wat onzichtbare vars voor het updaten
echo " <input type=\"text\" name=\"hoeveelheid_".$i."\" value=\"".$product[1]."\" size=\"2\" maxlength=\"2\" /></td>\n";
echo " <td class=\"rechtsuitlijnen\">"."€ ".$pro_cart->verkoopprijs."</td>"."\n";
$lineprice = $product[1] * $price; // regelprijs uitrekenen > hoeveelheid * prijs
echo " <td class=\"rechtsuitlijnen\">"."€ ".$lineprice."</td>\n";
echo " <td><a href=\"javascript:removeItem(".$i.")\">X</td>\n"; //Product verwijderen
echo "</tr>\n";
// Total
$total = $total + $lineprice; // Totaal updaten
}
?>
For displaying formatted numbers, you can use the PHP sprintf function ( http://php.net/manual/en/function.sprintf.php )
<?php
$money1 = 68.75;
$money2 = 54.35;
$money = $money1 + $money2;
// echo $money will output "123.1";
$formatted = sprintf("%01.2f", $money);
// echo $formatted will output "123.10"
?>
Use: bcadd()
echo bcadd(10.50, 12.75, 2);
returns 23.25
string number_format ( float $number [, int $decimals = 0 ] )
string number_format ( float $number , int $decimals = 0 , string $dec_point = '.' , string $thousands_sep = ',' )
Check out number_format documentation.

Adding numbers doesn't give expected results

I have 3 numbers returned from a database that I need to add together. For a total of 1,740.01, I get like 10.00. These are floating point numbers. Here are the actual numbers I'm having a problem with.
> 1,729.13
> 10.88
> 0.00
How do I get the correct total of these numbers?
EDIT
$cash = preg_replace('/\$/', '', $cash);
$card = preg_replace('/\$/', '', $card);
$check = preg_replace('/\$/', '', $check);
$cash = number_format(array_sum($cash), 2);
$card = number_format(array_sum($card), 2);
$check = number_format(array_sum($check), 2);
$total = number_format( $cash + $card + $check, 2 );
Don't add values that have been formatted using number_format(), otherwise they may well contain , as a thousand's separator... they're treated as strings rather than floats.
Assuming that $cash, $card and $check are arrays:
$cash = array_sum($cash);
$card = array_sum($card);
$check = array_sum($check);
$total = number_format( $cash + $card + $check, 2 );
$cash = number_format( $cash, 2 );
$card = number_format( $card, 2 );
$check = number_format( $check, 2 );
Do any formatting after the math
EDIT
Use str_replace() rather than preg_replace() to strip out any $, then it's simple addition rather than needing to do the array_sum(), though I'm not sure where any $ is likely to come from if the values are DECIMAL 10,7 from the database
$cash = (float) str_replace( array('$',','), '', $cash );
$card = (float) str_replace( array('$',','), '', $card );
$check = (float) str_replace( array('$',','), '', $check );
$total = number_format( $cash + $card + $check, 2 );
$cash = number_format( $cash, 2 );
$card = number_format( $card, 2 );
$check = number_format( $check, 2 );
(assumes that , is your thousands separator in the string values for $cash, $card and $check when doing the str_replace()
EDIT 2
To convert the $cash array to a sum of its values, having cleaned up any $ or , in the strings:
$cash = array ( 0 => '$1729.13', 1 => '0.00', 2 => '$1,234.56' );
function cleanArrayValues($value) {
return (float) str_replace( array('$',','), '', $value );
}
$cash = array_sum(array_map('cleanArrayValues',$cash));
I've added an extra value into the $cash array just to demonstrate.
You'll need to filter $card and $checks in the same way, using the cleanArrayValues() callback function (if they're all arrays)

Categories