PHP - Random round behavior issue
Asked Answered
D

4

11

I am actually facing a big problem with several websites (actually 3) based on Prestashop. The problem is that PHP or Prestashop randomly rounds prices to the nearest integer and it is not systematic.

Most of the time, it works perfectly, as it should, but sometimes (it can takes weeks or months between two problems), a price is rounded. My round mode option is correctly set to display two decimals.

The problem can occur when editing a product price in the back-office or when the customer is at the checkout step.

I tried to reproduce the problem, so I created a basic test: I retrieve a cart information and I display its price. I refreshed the page many times and I saw the price rounded a few times only. The most intriguous thing is that neither the context nor the code have changed between the beginning and the ending of the test.

I searched for help on Google and no one seemed to have this problem...

Did someone encounter this problem? Do you think it is a PHP issue or a Prestashop one? Thanks in advance for your help.

Here is the code of the round function Prestashop is using:

round($value, 2, PHP_ROUND_HALF_UP);

For information, the version of PHP 5.4.39.

Duodenitis answered 20/5, 2015 at 14:1 Comment(2)
php.net/round - there's 4 rounding methods. grep through prestashop's code to see which one(s) they're using.Indonesian
@MarcB Thanks for your suggestion, I've updated my question with the function used by Prestashop.Duodenitis
D
2

More than 2 years after, we figured out the issue. It was due to php5-fpm who does not handle locales per thread but per process. It is really clear in PHP documentation:

Warning The locale information is maintained per process, not per thread. If you are running PHP on a multithreaded server API like IIS, HHVM or Apache on Windows, you may experience sudden changes in locale settings while a script is running, though the script itself never called setlocale(). This happens due to other scripts running in different threads of the same process at the same time, changing the process-wide locale using setlocale().

Because the decimal separator has changed, PHP did not recognize decimals and truncated my numbers.

Duodenitis answered 5/10, 2017 at 14:57 Comment(0)
A
0

Maybe there is a problem if the price has a thousand-separator like 12,300.20?

Please have the following in mind:

Note: PHP doesn't handle strings like "12,300.2" correctly by default. See converting from strings.

See: http://php.net/round

Alberta answered 9/2, 2016 at 12:43 Comment(0)
L
0

I'm almost certain its how the floating point numbers are stored within your computer or something along those lines, that might point you in the right direction.

http://php.net/manual/en/language.types.float.php

Check this out as well, explaining about why floating point numbers dont always equal when you think they should. http://docstore.mik.ua/orelly/webprog/pcook/ch02_03.htm#phpckbk-CHP-2-SECT-3

Lithia answered 9/2, 2016 at 13:18 Comment(0)
O
0

There might be issues with locales. In german for example thousands separators and decimal points are the other way around. If you are not very careful handling those you might store wrong values in some persistence or break some value when casting it to float. Remember - when calculation with strings (eg: "2.55") php will cast them to float, handling german numbers ("2,55") will result in the wrong floating point number.

(float) "2.55" = 2.55
(float) "2,55" = 2

The issue can be fixed by configuring the locales correctly.

If you are able to tell a wrong result from a valid automatically, you might want to log the debug_backtrace at that point to evaluate the programs flow in that case.

Other answered 5/7, 2017 at 13:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.