为什么我必须再次舍入此值?

时间:2012-04-11 01:37:32

标签: php ajax

随着数量的增加,我正在使用ajax来生成图书的价格。我遇到的唯一问题是当我尝试生成总数时(参见JS代码)并且它引起了一些问题(值会连接而不是添加)。我通过舍入变量'amount'解决了这个问题。但我试图理解为什么连接发生了。这是我的PHP代码:

if(isset($_GET["amount1"]) )
{
    $amount1 = $_GET["amount1"];

    $error="";

    if($amount1 == "" || !preg_match("/^[0-9]+$/", $amount1))
    {
        $error .= "Please enter a valid number";
        echo $error;
    }
    else{
        echo round($amount1*16.65, 2);
    }
}

这是JS代码:

      if(xhr.status == 200 && xhr.readyState == 4)
      {
        var res = xhr.responseText;

        if(res.match(/\d+/)== null){
            document.getElementById("err3").innerHTML = res;
            document.getElementById("book3").innerHTML = "";
            total(0,3);
        }

        else{
            document.getElementById("book3").innerHTML = res;
            document.getElementById("err3").innerHTML = "";
            total(res,3);
          }
      }


var book1 = 0;
var book2 = 0;
var book3 = 0;

function total(amount, book)
{   
// amount = Math.round(amount*100)/100; --> this is what solved it but I don't    
 //know why I need it since amount was rounded by PHP code
if( book == 1)
    book1 = amount;

if( book == 2)
    book2 = amount;

if( book == 3)
    book3 = amount;

var total = book1 + book2 + book3;

document.getElementById("total").innerHTML = total;

}

由于

2 个答案:

答案 0 :(得分:4)

res是文字。使用前将其转换为数字。

js> parseFloat("3.14")
3.14

答案 1 :(得分:0)

它连接的原因是因为+运算符用于字符串连接和添加,这让我发疯。但更具体地说,这是因为输入到输入字段或从服务器传递给浏览器而没有某种包装器(json或xml)的值总是通过javascript处理为字符串,并且与PHP不同,javascript不支持类型杂耍(至少不在数字和字符串之间)。

由于这是通过ajax从php发回的,并且因为php正在处理数字验证,所以你真的只需要以json格式返回值并更新javascript以使用返回的对象,如下所示:

首先,PHP,稍微调整一下验证:

// 1. Using ctype_digit function to confirm value is >= 0. Much faster than regex
// 2. No need to round, as integer * float is always same or less precision, and
//    PHP sets product to appropriate numeric type.
// 3. Pushing values into array for json encoding
// 4. Setting both values (empty if invalid) so that javascript can easily confirm
//    response.
// 5. Updated Error, as negative numbers and floats are valid, 
//    just not in this case

$amount1 = $_GET["amount1"]);
$response["amount1"] = (ctype_digit($amount1)) ? $amount1 * 16.65 : "";
$response["error"] = (ctype_digit($amount1)) ? "" : "Please enter a valid quantity";

echo json_encode($response);

现在,javascript必须使用eval()将响应字符串反序列化为对象,并获取总数和其他内容:

javascript(再次,一些小调整,这次没有笔记)

if(xhr.status == 200 && xhr.readyState == 4)
{
    var res = eval("(" + xhr.responseText + ")"); 

    amount1 = (!isNaN(res.amount1)) ? res.amount1 : "";     

    document.getElementById("err3").innerHTML = res.error;
    document.getElementById("book3").innerHTML = res.amount1;
    document.getElementById("total").innerHTML = total(Number(res.amount1),3);
}

var book1 = 0;
var book2 = 0;
var book3 = 0;

function total(amount, book)
{
switch (book) {
   case 1:
      book1 = amount;
      break;
   case 2:
      book2 = amount;
      break;
   case 3:
      book3 = amount;
      break;
}

return book1 + book2 + book3;
}

现在,您可能会注意到,当我最终将amount1值传递给total函数时,我实际将其包装在Number()函数中,这几乎解决了问题而不使用JSON。理论上,如果PHP总是返回一个数值,我不需要这样做。以下是我将其转换为数字类型的原因,尽管如此:

  1. 因为js没有为数字打字,所以这只是一个好主意。你永远不会知道PHP在糟糕的一天可能会返回什么,并且验证应该在通信的两端进行。

  2. 这允许PHP返回值的空字符串,您可以将其输出给用户,然后Number()将空字符串设置为0以获取总函数。< / p>

  3. 如果您决定跳过ajax方法并在浏览器端进行定价计算,则必须始终使用Number()转换值,因此这是一个很好的(虽然很烦人)习惯在处理来自任何外部来源的数值时。

  4. 我会在一些jsfiddle中发布一个最终版本的最终版本,我将如何实现你的总体目标,你可以忽视或偷窃,我只是觉得这样做。