VARCHAR SQL contains numbers how to get 2 decimals after comma - php

I'm having some trouble getting the price to show correct on my website. Currently i have a row VerkoopPP40 which is a VARCHAR input. In this row there is a price e.g. 89,5 or just 9. When I try to get these values it does some unexpected things.
**** Update ****
I've just tried this code:
<?php
function formatNumber($number, $format=[], $oldDecimalSeparator=",.·'", $multiplier=1)
{
if ($format) {
$format += ['numOfDecimals' => 0, 'decimalSeparator' => '.', 'thousandSeparator' => '']; # Default format
# Find decimal separator
# The decimal separator is the one that is the last and does not occur more than once
if ($letters = str_replace(' ', '', $number)) { # Replace spaces
if ($letters = preg_replace('/^-/', '', $letters)) { # Remove minus
if ($letters = preg_replace('/[0-9]/', '', $letters)) { # Get all non digits
$lastletter = substr($letters, -1); # Returns last char
if (substr_count($letters, $lastletter) == 1) {
if (strpos($oldDecimalSeparator, $lastletter) !== false)
$oldDecimalSep = $lastletter;
else
return $number;
}
}
}
}
$number = preg_replace('/[^0-9-]/', '', $number); # Remove all non digits except 'minus'
if ($oldDecimalSep)
$number = str_replace($oldDecimalSep, '.', $number); # Format to float
if ($multiplier != 1)
$number = $number * $multiplier;
# Convert float to new format
$number = number_format($number,
$format['numOfDecimals'],
$format['decimalSeparator'],
$format['thousandSeparator']
);
}
return $number;
}
This returns: 9,00 and 895,00 so the comma is in a different place right now. It's something I guess... Anyone got an idea to move the comma and remove a 0.
**** End Update ****
And echo-ed it like this:
<td><p>vanaf " . formatNumber($number, [
'numOfDecimals' => 2,
'decimalSeparator' => ',',
'thousandSeparator' => ' '
], ',.') . " p.p. <small>Excl btw</small></p></td>
If I just echo the VerkoopPP40 row it returns: €89,5 or €9.
So I googled around some and found this:
$var = $row["VerkoopPP40"];
$var = ltrim($var, '0');
$foo = $var;
$prijzen = number_format($foo, 2, ',', '');
This turns the . into a ,. But also returns €9,00 for the row that has 9 in it. But the strange thing is the row that has 89.5 in it now just returns €89,00. So somewhere in the code it rounds the numbers down.
Does anyone know how to get the price to show just €9,00 and €89,50 respectively.
I tried the following codes as well:
SELECT ROUND(VerkoopPP40,2) AS RoundedPrice
As database query. That didn't work.
$prijzen = CAST($prijzen as decimal(2,2));
Also didn't work. Any more ideas?

Don't know if this will help you, but found in the comments of the PHP doc : "To prevent the rounding that occurs when next digit after last significant decimal is 5 (mentioned by several people)..." read more
$num1 = "89,5";
$num2 = str_replace(',', '.', $num1);
$price = number_format($num2, 2, '.', '');
echo"[ $price ]";

you should use number_format but in the right way let me explain it to you
you tried this with 89.5
$prijzen = number_format($foo, 2, ',', '');
but this is written for 89,5 not for 89.5
//this will work for you
$var = $row["VerkoopPP40"];
echo 'raw output from database is :'.$var;
$var = $var / 10;
echo 'after this step the number is :'.$var;
$var = number_format($var, 2, '.', '');
echo 'after this step the number is :'.$var;
number_format(the input number, decimal places, 'the divider between whole numbers and decimals', '')

Related

PHP 'NumberFormatter' 'SPELLOUT' is not providing required format in english

I Am using PHP NumberFormatter in my code to convert price value in words
for example, if it is rupees 125 then it should be 'One hundred and twenty five' instead of 'one hundred twenty five'.
I have tried the other examples like checking each digit unit value and replace the words
$numberFormatterClass = new \NumberFormatter("en", \NumberFormatter::SPELLOUT);
echo str_replace('-', ' ', $numberFormatterClass->format($number));
expecting for 125 = "One hundred and twenty five"
When the number is above 99 you can generate the spellout for the last two digits only. You then know where to insert the "and". In code:
$number = 125;
$numberFormatter = new \NumberFormatter('en', \NumberFormatter::SPELLOUT);
$fullSpellout = str_replace('-', ' ', $numberFormatter->format($number));
if ($number > 100) {
$lastTwoSpellout = str_replace('-', ' ', $numberFormatter->format(substr($number, -2)));
$hunderdsLength = strlen($fullSpellout) - strlen($lastTwoSpellout);
$fullSpellout = substr($fullSpellout, 0, $hunderdsLength) . 'and ' . $lastTwoSpellout;
}
echo $fullSpellout;
This outputs:
one hundred and twenty five
This is certainly not the only possible solution. There are many ways to insert the "and", and if the last two digits always generate two words you could also use that to detect where to insert the "and".
Here's a version based on words and using an array to insert the 'and':
$number = 125;
$numberFormatter = new \NumberFormatter('en', \NumberFormatter::SPELLOUT);
$spellout = str_replace('-', ' ', $numberFormatter->format($number));
if ($number > 100) {
$words = explode(' ', $spellout);
array_splice($words, -2, 0, ['and']);
$spellout = implode(' ', $words);
}
echo $spellout;

Get range letter and number with php

how can I get range for bottom string in php?
M0000001:M0000100
I want result
M0000001
M0000002
M0000003
..
..
..
M0000100
this is what i do
<?php
$string = "M0000001:M0000100";
$explode = explode(":",$string );
$text_one = $explode[0];
$text_two = $explode[1];
$range = range($text_one,$text_two);
print_r($range);
?>
So can anyone help me with this?
This is one of many ways you could do this and this is a little verbose but hopefully it shows you some "steps" to take.
It doesn't check for the 1st number being bigger than the 2nd.
It doesn't check your Range strings start with a "M".
It doesn't have all of the required comments.
Those are things for you to consider and work out...
<?php
$string = "M00000045:M000099";
echo generate_range_from_string($string);
function generate_range_from_string($string) {
// First explode the two strings
$explode = explode(":", $string);
$text_one = $explode[0];
$text_two = $explode[1];
// Remove the Leading Alpha character
$range_one = str_replace('M', '', $text_one);
$range_two = str_replace('M', '', $text_two);
$padding_length = strlen($range_one);
// Build the output string
$output = '';
for ( $index = (int) $range_one; $index <= (int) $range_two; $index ++ ) {
$output .= 'M' . str_pad($index, $padding_length, '0', STR_PAD_LEFT) . '<br>';
}
return $output;
}
The output lists a String in the format you have specified in the question. So this is based solely upon that.
This could undergo a few more revisions to make it more function like, as I'm sure some folks will pick out!

PHP - For Loop Keep Significant Digits [duplicate]

This question already has answers here:
Zero-pad digits in string
(5 answers)
Closed 2 years ago.
I have a variable which contains the value 1234567.
I would like it to contain exactly 8 digits, i.e. 01234567.
Is there a PHP function for that?
Use sprintf :
sprintf('%08d', 1234567);
Alternatively you can also use str_pad:
str_pad($value, 8, '0', STR_PAD_LEFT);
Given that the value is in $value:
To echo it:
printf("%08d", $value);
To get it:
$formatted_value = sprintf("%08d", $value);
That should do the trick
When I need 01 instead of 1, the following worked for me:
$number = 1;
$number = str_pad($number, 2, '0', STR_PAD_LEFT);
echo str_pad("1234567", 8, '0', STR_PAD_LEFT);
sprintf is what you need.
EDIT (somehow requested by the downvotes), from the page linked above, here's a sample "zero-padded integers":
<?php
$isodate = sprintf("%04d-%02d-%02d", $year, $month, $day);
?>
Though I'm not really sure what you want to do you are probably looking for sprintf.
This would be:
$value = sprintf( '%08d', 1234567 );
Simple answer
$p = 1234567;
$p = sprintf("%08d",$p);
I'm not sure how to interpret the comment saying "It will never be more than 8 digits" and if it's referring to the input or the output. If it refers to the output you would have to have an additional substr() call to clip the string.
To clip the first 8 digits
$p = substr(sprintf('%08d', $p),0,8);
To clip the last 8 digits
$p = substr(sprintf('%08d', $p),-8,8);
If the input numbers have always 7 or 8 digits, you can also use
$str = ($input < 10000000) ? 0 . $input : $input;
I ran some tests and get that this would be up to double as fast as str_pad or sprintf.
If the input can have any length, then you could also use
$str = substr('00000000' . $input, -8);
This is not as fast as the other one, but should also be a little bit faster than str_pad and sprintf.
Btw: My test also said that sprintf is a little faster than str_pad. I made all tests with PHP 5.6.
Edit: Altough the substr version seems to be still very fast (PHP 7.2), it also is broken in case your input can be longer than the length you want to pad to. E.g. you want to pad to 3 digits and your input has 4 than substr('0000' . '1234', -3) = '234' will only result in the last 3 digits
$no_of_digit = 10;
$number = 123;
$length = strlen((string)$number);
for($i = $length;$i<$no_of_digit;$i++)
{
$number = '0'.$number;
}
echo $number; /////// result 0000000123
I wrote this simple function to produce this format: 01:00:03
Seconds are always shown (even if zero).
Minutes are shown if greater than zero or if hours or days are required.
Hours are shown if greater than zero or if days are required.
Days are shown if greater than zero.
function formatSeconds($secs) {
$result = '';
$seconds = intval($secs) % 60;
$minutes = (intval($secs) / 60) % 60;
$hours = (intval($secs) / 3600) % 24;
$days = intval(intval($secs) / (3600*24));
if ($days > 0) {
$result = str_pad($days, 2, '0', STR_PAD_LEFT) . ':';
}
if(($hours > 0) || ($result!="")) {
$result .= str_pad($hours, 2, '0', STR_PAD_LEFT) . ':';
}
if (($minutes > 0) || ($result!="")) {
$result .= str_pad($minutes, 2, '0', STR_PAD_LEFT) . ':';
}
//seconds aways shown
$result .= str_pad($seconds, 2, '0', STR_PAD_LEFT);
return $result;
} //funct
Examples:
echo formatSeconds(15); //15
echo formatSeconds(100); //01:40
echo formatSeconds(10800); //03:00:00 (mins shown even if zero)
echo formatSeconds(10000000); //115:17:46:40
You can always abuse type juggling:
function zpad(int $value, int $pad): string {
return substr(1, $value + 10 ** $pad);
}
This wont work as expected if either 10 ** pad > INT_MAX or value >= 10 * pad.

Show decimal point number in PHP

I hold decimals in a database using DECIMAL(10,5)
I would like to format these numbers according to a few rules:
A zero decimal should display as 0
Show a long decimal (no trailing zero's) with all of it's numbers
When possible, I would like to only show up to 2 decimal places (when there are trailing zeros)
Here are some examples:
The left side corresponds to how the number is stored in database.
The right number is how I would like to display the number in my application.
0.00000 => 0
0.51231 => 0.51231
0.12000 => 0.12
0.40000 => 0.40
0.67800 => 0.678
12.10000 => 12.10
This will work for you:
function format($x){
if(!(int)substr_replace($x, '', $dpos = strpos($x, '.'), 1))
return 0;
else
return str_pad((rtrim($x, '0')), $dpos + 3, '0');
}
Example
I would utilize the number_format function in php to actually do the formatting after you determine the amount of decimal places to the number has.
Source:
http://php.net/manual/en/function.number-format.php
Example Usage:
$number = 1234.56;
// english notation (default)
$english_format_number = number_format($number);
// 1,235
// French notation
$nombre_format_francais = number_format($number, 2, ',', ' ');
// 1 234,56
$number = 1234.5678;
// english notation without thousands separator
$english_format_number = number_format($number, 2, '.', '');
// 1234.57
Well here's one way (I haven't tested it yet so there may be minor errors):
$pattern = '/([0-9]+)\\.{0,1}([0-9]*?)0*$/';
$subject = 12.10000;
$matches = array();
$result = preg_match ($pattern, $subject, $matches);
$number = $matches[1];
if ($matches[2] != 0) {
$number .= '.'.$matches[2];
if ($matches[2] < 10) {
$number .= '0';
}
}
echo $number;
And here's another way (probably a little faster):
$x = 1.000;
$result = (int)$x;
$trimmed = rtrim($x, 0);
if ($trimmed[strlen($trimmed) - 1] != '.') {
if ($trimmed[strlen($trimmed) - 2] == '.') {
$result = $trimmed.'0';
} else {
$result = $trimmed;
}
}
echo $result;
I haven't used it myself, but theres the NumberFormatter class: http://php.net/manual/class.numberformatter.php as part of the Internationalization Functions for this stuff. Using that is a little more involved i think though.
I know this is an old question, but the following quick function I wrote for my own project might help someone looking for this.
function number_format_least_dp($number, $decimal_point = '.', $thousand_seperator = ','){
if (floatval($number) == (int)$number){
$number = number_format($number, 0, $decimal_point, $thousand_seperator);
} else {
$number = rtrim($number, '.0');
$number = number_format($number, strlen(substr(strrchr($number, '.'), 1)), $decimal_point, $thousand_seperator);
}
return $number;
}

Formatting a number with leading zeros in PHP [duplicate]

This question already has answers here:
Zero-pad digits in string
(5 answers)
Closed 2 years ago.
I have a variable which contains the value 1234567.
I would like it to contain exactly 8 digits, i.e. 01234567.
Is there a PHP function for that?
Use sprintf :
sprintf('%08d', 1234567);
Alternatively you can also use str_pad:
str_pad($value, 8, '0', STR_PAD_LEFT);
Given that the value is in $value:
To echo it:
printf("%08d", $value);
To get it:
$formatted_value = sprintf("%08d", $value);
That should do the trick
When I need 01 instead of 1, the following worked for me:
$number = 1;
$number = str_pad($number, 2, '0', STR_PAD_LEFT);
echo str_pad("1234567", 8, '0', STR_PAD_LEFT);
sprintf is what you need.
EDIT (somehow requested by the downvotes), from the page linked above, here's a sample "zero-padded integers":
<?php
$isodate = sprintf("%04d-%02d-%02d", $year, $month, $day);
?>
Though I'm not really sure what you want to do you are probably looking for sprintf.
This would be:
$value = sprintf( '%08d', 1234567 );
Simple answer
$p = 1234567;
$p = sprintf("%08d",$p);
I'm not sure how to interpret the comment saying "It will never be more than 8 digits" and if it's referring to the input or the output. If it refers to the output you would have to have an additional substr() call to clip the string.
To clip the first 8 digits
$p = substr(sprintf('%08d', $p),0,8);
To clip the last 8 digits
$p = substr(sprintf('%08d', $p),-8,8);
If the input numbers have always 7 or 8 digits, you can also use
$str = ($input < 10000000) ? 0 . $input : $input;
I ran some tests and get that this would be up to double as fast as str_pad or sprintf.
If the input can have any length, then you could also use
$str = substr('00000000' . $input, -8);
This is not as fast as the other one, but should also be a little bit faster than str_pad and sprintf.
Btw: My test also said that sprintf is a little faster than str_pad. I made all tests with PHP 5.6.
Edit: Altough the substr version seems to be still very fast (PHP 7.2), it also is broken in case your input can be longer than the length you want to pad to. E.g. you want to pad to 3 digits and your input has 4 than substr('0000' . '1234', -3) = '234' will only result in the last 3 digits
$no_of_digit = 10;
$number = 123;
$length = strlen((string)$number);
for($i = $length;$i<$no_of_digit;$i++)
{
$number = '0'.$number;
}
echo $number; /////// result 0000000123
I wrote this simple function to produce this format: 01:00:03
Seconds are always shown (even if zero).
Minutes are shown if greater than zero or if hours or days are required.
Hours are shown if greater than zero or if days are required.
Days are shown if greater than zero.
function formatSeconds($secs) {
$result = '';
$seconds = intval($secs) % 60;
$minutes = (intval($secs) / 60) % 60;
$hours = (intval($secs) / 3600) % 24;
$days = intval(intval($secs) / (3600*24));
if ($days > 0) {
$result = str_pad($days, 2, '0', STR_PAD_LEFT) . ':';
}
if(($hours > 0) || ($result!="")) {
$result .= str_pad($hours, 2, '0', STR_PAD_LEFT) . ':';
}
if (($minutes > 0) || ($result!="")) {
$result .= str_pad($minutes, 2, '0', STR_PAD_LEFT) . ':';
}
//seconds aways shown
$result .= str_pad($seconds, 2, '0', STR_PAD_LEFT);
return $result;
} //funct
Examples:
echo formatSeconds(15); //15
echo formatSeconds(100); //01:40
echo formatSeconds(10800); //03:00:00 (mins shown even if zero)
echo formatSeconds(10000000); //115:17:46:40
You can always abuse type juggling:
function zpad(int $value, int $pad): string {
return substr(1, $value + 10 ** $pad);
}
This wont work as expected if either 10 ** pad > INT_MAX or value >= 10 * pad.

Categories