【问题标题】:Comparing string - woes in PHP比较字符串 - PHP 中的问题
【发布时间】:2009-12-26 13:08:35
【问题描述】:

我想让用户输入优惠券号码以获得折扣。输入并提交优惠券号码后,页面会重新加载,并显示他们输入了正确的金额。

如果优惠券金额 0.00 英镑,我尝试这样做的方法是显示勾号。但是字符串比较似乎不起作用,因为它总是认为它不是 0.00 英镑。代码如下。函数 coupon_amount() 返回票面金额。 coupon_amount() 返回“£0.00”(包括英镑符号)

<?php $coup_amount = coupon_amount(); ?>
<?php $zero_amount = "£0.00"; ?>

<?php if(strcmp($coup_amount, $zero_amount)== 0) { ?>

 <?php echo 'Enter coupon code if applicable:' ?>
 <input type='text' class='couponinput' name='coupon_num' id='coupon_num' value='coupons_name' />
 <input type='submit' class='update-button' value='submitcoupon' />

<?php } else {  ?>

 <?php echo 'Thanks.' ?><input type='text' disabled='disabled' class='couponinput' name='coupon_num' id='coupon_num' value='coupons_name' />
 <div class='tick'></div>

<?php }  ?>

我在比较方面做错了吗?

我按照 Oscar 的建议在下面,这是输出。似乎是编码问题。并且对于 zero_amount,英镑符号没有正确显示。

coup_amount: (£0.00)  zero_amount: (�0.00) 
coup_len:10 zero_len:5
strcmp: -1
coup_ascii: 38 zero_ascii:163

【问题讨论】:

  • 您对优惠券金额使用字符串值(带有 £ 符号)而不是数字变量是否有特定原因?
  • 注意不要使用浮点数。大脑中的 0.33 英镑与计算机中的不一样。我建议用便士建模并使用整数。
  • @samir 为什么不一样?
  • coupon_amount() 返回“£0.00”(包括英镑符号)
  • 好吧..我以为我能闻到编码问题:)(更新了我的帖子..)

标签: php string strcmp


【解决方案1】:

您确实应该将折扣值存储/使用为数字,这将使比较更容易。

【讨论】:

    【解决方案2】:

    你试过打印出所有的值吗?

    <?php $coup_amount = coupon_amount(); ?>
    <?php $zero_amount = "£0.00"; ?>
    
    //print'em out
    <pre>
    <?php 
      echo "coup_amount: ($coup_amount)  zero_amount: ($zero_amount) \n";
      echo "coup_len:".strlen($coup_amount)." zero_len:".strlen($zero_amount)."\n";
      echo "strcmp: ".strcmp($coup_amount, $zero_amount)."\n";
      echo "coup_ascii: ".ord($coup_amount[0])." zero_ascii:".ord($zero_amount[0]);
    ?>
    </pre>
    

    修正
    所以是的,现在我们可以看到这个输出,看起来政变字符串是一个 UTF16(10 个字节长),另一个是别的东西(5 个字节长)。

    (接着讲道。)在处理金钱时,你真的应该格外小心,以确保正确处理数字。我们刚刚看到字符串会受到编码的影响,并且就像其他人指出的那样,浮点数会受到小数误差的影响。您最好的选择可能是尝试使用整数以 1/100 表示,并在单独的变量中表示货币。 (讲道。)

    但我猜coupon_amount-function 无处不在,你无法更改它。然后你可能想考虑转换这两个字符串,以便它们的格式相同。看看iconv

    【讨论】:

    • 谢谢。用输出修改了我的问题。似乎是编码问题和井号问题?
    • 使用 iconv 让它工作 - 请参阅我的答案。我相信有更简单的方法:)
    【解决方案3】:
    <?php if(strcmp($coup_amount, $zero_amount)== 0) { ?>
    

    与以下相比似乎非常难以理解:

    <?php if(coupon_amount() == 0) { ?>
    

    如果 coupon_amount() 返回的是实际值,而不是格式化的字符串表示形式。

    您是否可以更改 coupon_amount() 函数以摆脱英镑符号? php 函数money_format 非常适合将用户货币符号添加到字符串中以显示在页面上(或者您将语言环境设置为哪个符号)

    将来你会发现自己必须先删除英镑符号,然后才能对来自 coupon_amount() 的返回值进行任何算术运算

    【讨论】:

      【解决方案4】:

      有很多东西对用户来说似乎无关紧要,但可能会破坏字符串比较

      • coupon_amount() 可能会在返回值的某处插入一些空格
      • coupon_amount() 可能返回可变数量的零
      • coupon_amount() 可以使用逗号代替点(取决于语言环境)
      • coupon_amount() 可以使用一些 HTML 实体对磅符号进行编码

      也就是说,最好是比较数值,然后将数字格式化为货币。

      【讨论】:

        【解决方案5】:

        strcmp 调用似乎没问题,我赌的是 coupon_amount 函数。

        【讨论】:

          【解决方案6】:

          为了让它发挥作用,我不得不费尽心思:) .. 我将第一个 if 语句更改为:

          if((ord($coup_amount[0])==38) && (ord($coup_amount[1])==35) 
          && (ord($coup_amount[2])==49) && (ord($coup_amount[3])==54) 
          && (ord($coup_amount[4])==51) && (ord($coup_amount[5])==59) 
          && (ord($coup_amount[6])==48) && (ord($coup_amount[7])==46) 
          && (ord($coup_amount[8])==48) && (ord($coup_amount[9])==48) 
          && (ord($coup_amount[10])==0)) 
          

          【讨论】:

            【解决方案7】:

            您是否尝试过在没有井号的情况下比较它?.. 像这样

            substr($coup_amount, 1) == "0.00";
            

            我发现您在检索井号时遇到问题,所以我认为最好尝试一下。

            【讨论】:

              猜你喜欢
              • 2011-06-03
              • 2012-02-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-05-04
              相关资源
              最近更新 更多