0

I have a form that uses jQuery to calculate totals before submission. It sends the total along with the currency symbol to the form handling script. This is generating some

Warning: A non-numeric value encountered

messages, so I have been using str_replace. However, the following code is still generating the errors. It works everywhere else apart from this one section of code and I cannot find a solution. Could anyone help with some advice.

function netprice() {
    $vatrate = 1.2;
    $gross = str_replace('£','',$_POST['unit_Price']);
    $net = round(($gross / $vatrate) , 2);

    if (empty($gross)) {
        echo"-";
    }else{
        echo $net;
    }
}
Qirel
  • 25,449
  • 7
  • 45
  • 62
Gareth
  • 3
  • 2
  • 1
    What does `$_POST['unit_Price']` contain? `var_dump()` it and show us. – Qirel Mar 10 '17 at 22:43
  • Hi Qirel. var_dump shows this string(0) "" – Gareth Mar 10 '17 at 23:02
  • That means no corresponding `` (notice the case) is present in the form passed into PHP. Also, you should explicitly typecast the variable into an integer by using `intval()` to avoid future confusions. – tyteen4a03 Mar 10 '17 at 23:57

6 Answers6

2

You can use filter_var function to get only number from string.

$gross = filter_var($_POST['unit_Price'], FILTER_SANITIZE_NUMBER_INT);

If you want to get float use:

$gross = filter_var($_POST['unit_Price'], FILTER_SANITIZE_NUMBER_FLOAT);
TheMY3
  • 353
  • 3
  • 10
  • It's a good solution, but what if it is a float and not an integer? – Qirel Mar 10 '17 at 22:51
  • This won't work as expected because price values can be float. For example `$gross = filter_var('£1.2', FILTER_SANITIZE_NUMBER_INT);` will return (string)12 – aperpen Mar 10 '17 at 22:54
  • @Qirel add this to in answer – TheMY3 Mar 10 '17 at 22:54
  • Cheers for this mate. I did not see your answer for float until it was too late, otherwise this would have been the answer I selected. – Gareth Mar 11 '17 at 00:00
2

Instead of using str_replacethat could be leaving spaces or other chars, you could use preg_replaceas in the example here Remove non-numeric characters (except periods and commas) from a string

your code would look like this:

function netprice() {

$vatrate = 1.2;

$gross = preg_replace("/[^0-9,.]/", "", $_POST['unit_Price']);
$net = round(($gross / $vatrate) , 2);

    if (empty($gross)) {

        echo"-";

    }else{

        echo $net;
    }
}

preg_replace will strip out all chars except for those defined in the first argument.

Community
  • 1
  • 1
naui95
  • 31
  • 1
  • 3
1

You really shouldn't send the currency symbol with the form. If you cannot avoid it, there may be other characters such as a space between the symbol and the number. First off you could try passing the resulting value through floatval() like such:

$gross = floatval(str_replace('£','',$_POST['unit_Price']));

If it still doesn't work, use regex instead to strip every character except for numbers, commas and dots:

$gross = floatval(preg_replace('/[^0-9,.]/', '', $_POST['unit_Price']));
Pejka
  • 141
  • 4
  • This is an important point. The currency shouldn't be dictated on the client-side. – Ibu Mar 10 '17 at 23:02
  • This did the trick. Thanks for that Pejka. And thanks to everyone for all your suggestions. Greatly appreciated :) – Gareth Mar 10 '17 at 23:25
  • You're welcome. As per Yaroslav Molchan's answer, you should also consider using filter_var() to get $_POST values instead of directly accessing it. Using raw form inputs can be a vulnerability. – Pejka Mar 10 '17 at 23:35
  • Will do. Thanks again buddy. – Gareth Mar 11 '17 at 00:01
0

Change £ to £

Also check your output, which data contains $gross after str_replace

chris85
  • 23,846
  • 7
  • 34
  • 51
Chris Toxz
  • 13
  • 9
0

If your currency symbol is before the value, you can use a substr:

<?php
$price = substr('£1.2', 2); //1.2

Note that because £ symbol is an special char you must substract 2 first chars. You can check it by doing a var_dump

If your currency symbol is at the end, you can simply force de value to be float:

$price = (float)'1.2£'; //1.2
aperpen
  • 718
  • 7
  • 10
0

Thanks for all your help guys. I went with Pejka's solution

$gross = floatval(preg_replace('/[^0-9,.]/', '', $_POST['unit_Price']));

I really appreciate all your help. A thousand thanks :)

Gareth
  • 3
  • 2