PHP processing user-friendly formatted prices to standard floats - php

I have a form in which users can enter prices for items. Ideally I want the user to be able to add prices in whatever method feels best to them and also for readability. I then need to convert this to a standard float so that my web service can calculate costs etc.
The part I'm struggling with is how to take the initial sting/float/int of currency and convert it into a float.
For example:
UK: 1,234.00
FRA: 1 234,00
RANDOM: 1234
RANDOM2: 1234.00
All of those have slightly different formats.
Which I would want to store as:
1234.00
I will then store the result in MySQL database as a DECIMAL.
Any help would be great.

Assuming you're using MySQL, use the DECIMAL or NUMERIC type are the correct types used for storing currency.
Float's are susceptible to rounding errors and have a limited precision.
The formatting for display should be handled by PHP.
If storing in DB, you should of course store a currency code - which can be used when retrieving to tell PHP how to display it

Couldn't you use:
floatval($AnyVar)

In a case where you'd like to accept so many different formats it's a bit tricky to get it right.
Now we can just use a simple regex to get the decimal and full parts of the value:
/^([0-9,. ]+?)(?:[.,](\d{1,2})$|$)/
The regex will capture the full part of the number + a decimal part, separated with a , or a . and which has one or two numbers.
The capture group 1 will contain the full part, and group 2 the decimal part (if any).
To get your number, you just need to filter out all non-numeric characters from the full part, and join the filtered full and decimal parts together.
If you want to make it more foolproof, you probably should implement something on the client-side to guide the user to input the value in the correct format.

Related

SQL BETWEEN prices stored as string

I'm running into a problem here. I'm storing prices in my database as a string in the following format: 14.500,00 and 199,95. Sometime later I created this range slider so the users can filter on price as you can see in the provided image. For this to work, I needed to write a new query so I was thinking of a BETWEEN in SQL but this doesn't work on strings. Any ideas to filter on price with a range slider in SQL?
BETWEEN does work on strings. It works just fine -- with the strings ordered alphabetically.
Your problem is that BETWEEN on strings doesn't follow the numeric ordering. Well, that is normal. If I'm speaking French, I wouldn't expect an English speaker to understand me. The same with types. If I use BETWEEN on strings, then I expect the comparisons to be string-based, not numeric. (The same is true of dates, by the way.)
Fix your data so the values are stored as numeric/decimal values. These are numbers with a fixed number of decimal places, exactly what is needed for monetary values.
In most databases, you will need to get rid of the dollar sign. Something like this should work:
update t
set price = replace(price, '$', '');
alter table t alter column price numeric(10, 2); -- or whatever is appropriate
The exact syntax might vary, depending on the database.

php comma and decimal format

I just want to ask if there is any PHP/MySQL datatype that can store a number with a comma and decimal such as 10,000.35
when the user hit the save button with this value, it should be stored in a MySQL table and the system can retrieve it also to be processed as number 10000.35
thanks for any help!
That would be a CHAR/string datatype.
Numeric values don't have formats. They only contain the numeric value. Commas are not relevant for numeric computation. Format the values on output using, for instance, number_format. That's the only time a comma is relevant, it does not need to be stored.
Store the number without the comma in MySQL and just format the number in PHP when you are displaying it. It would be easier to keep the number without the comma in PHP as well if you're doing math with it - only use the comma when displaying the data!
If you are going to be storing numeric values it is best to leave all the formatting out of it.
For instance, what if you need to localize the display so that 10,000.05 needs to be 10.000,05? You'd have a lot of work to do.
You should store the value in the database as 10000.05 and use number_format($myValue,2,'.',','); to display the value when it's time. This will allow you to change the literals to variables or constants should you ever have to localize. It will also allow you to configure how many decimal places you care to display.
Here's the PHP docs for number_format()
It would be best to store it in your MySQL database without the comma, and then using PHP's number_format to display it with the commas.
The MySQL datatype that does this is DECIMAL. DECIMAL gives you fixed decimal places without the precision errors inherent in float type. (ie 123.45 instead of 123.4499999999999999)
You have 2 options , using MySQL to format directly or Using PHP .... see below for examples
MySQL Direct Solution
SELECT FORMAT(number, 2) as formatNumber FROM table ;
PHP Solution
number_format($number,2,'.',',');
Thanks
:)

MySQL - Best way to store currency symbols?

Just wondering what the best way of storing currency values and symbols within a MySQL DB might be?
Thanks to browsing SO, I'm storing my amounts as a Decimal (19,2) value - which is fine - but am more concerned with the Currency symbol (e.g. €, £, $, etc.), as I want to allow the end user to set their own currency unit at the set up stage. I also want to avoid any uncertainty as regards, which are currently set at utf8 (both sides).
The way I have at the moment is to store them as HTML Numerical Codes using PHP ifelse statements to filter input. Is this the best method? If not, what is? Is there a need at all? Many thankee's in advance!
imho, you can break the data into two columns
amount = decimal(19,2) --- question : unsigned for positive value only
currency_id = int(10) unsigned --- which is ID to currency table
when the currency field is reference to another table,
you can storing all sort of additional info into that table (such as exchange rate)
to better describe how you want the symbol get presented
I would use a character (3) and store the currency code instead ( http://en.wikipedia.org/wiki/ISO_4217#Active_codes ). For example, EUR, USD, GBP etc., and only show the appropriate symbol at display-time.
Have you considered not using symbols at all, but using ISO 4217 three letter codes instead?
If necessary, use another table to handle mapping from those into a more user-friendly symbol format on output.
Do you have to convert the currency based on what the user choose? If yes, you can just make a new table for storing the currency symbol and the exchange rate.
If you just want to show the currency based on the user's locale, you may want to try an internationalization library.

Accepting values containing multiple point system

How do i accept values from user that contain multiple points like 1.2.1...if i use float--1.2.1 gets converted to 1.2.
Thanks.
the simple answer: if u want multiple points DONT USE FLOAT :-)
use something like varchar or text instead
Treat it as text.
A float is used to represent Real numbers, and "1.2.1" is not a Real number.
Or, if "1.2.1" is simply a grouping of numbers, you could split the input of "1.2.1" into three separate numbers using the period as a delimiter, and store them as distinct numbers.

Add all lines multiplied by another line in another table

I hope I can explain this good enough. I have 3 tables. wo_parts, workorders and part2vendor. I am trying to get the cost price of all parts sold in a month. I have this script.
$scoreCostQuery = "SELECT SUM(part2vendor.cost*wo_parts.qty) as total_score
FROM part2vendor
INNER JOIN wo_parts
ON (wo_parts.pn=part2vendor.pn)
WHERE workorder=$workorder";
What I am trying to do is each part is in wo_parts (under partnumber [pn]). The cost of that item is in part2vendor (under part number[pn]). I need each part price in part2vendor to be multiplied by the quantity sold in wo_parts. The way all 3 tie up is workorders.ident=wo_parts.workorder and part2vendor.pn=wo_parts.pn. I hope someone can assist. The above script does not give me the same total as when added by calculator.
This is not an answer, just a comment.
Why don't you take the sum/multiply operation outside the SQL statement? I know, that seems stupid because it will increase the lines of code and the complexity of the script, but, imho, it is always a good thing to keep code and SQL statements as far away as possible.
The key cause I could see for something like this would be a type issue. For example, this could happen if you are using FLOATs instead of NUMERICs, you might get a slightly different answer. That is a mistake that is way too common, btw.
I would recommend double checking your schema to make sure you are using NUMERICs across the board here. NUMERIC is crazy-powerful on PostgreSQL, it performs very well, and it properly supports arbitrary precision operations. If you can't change the data type, cast your fields to numeric in your query.
FLOAT types (including DOUBLE) are fixed precision binary numbers, and they don't correspond exactly to base 10 numbers always. NUMERICs are stored internally as base 1000 (meaning 9 digits per 30 bits), and this is very efficient to convert to/from binary. The precision is also arbitrary, although it does have a maximum. However, for financial stuff, the maximum values or precision are not an issue with numeric data types. You should use them liberally.

Categories