Сравнение строки - горе в PHP - PullRequest
0 голосов
/ 26 декабря 2009

Я хочу разрешить пользователю вводить номер купона, чтобы получить скидку. После того, как номер купона введен и отправлен, страница обновляется с галочкой, показывающей, что они ввели правильную сумму.

Способ, которым я пытаюсь это сделать, заключается в отображении галочки, если сумма купона составляет , а не £ 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 }  ?>

Я что-то не так сравниваю?

Я последовал предложению Оскара ниже, и вот вывод. Кажется, это проблема кодирования. И знак фунта не отображается должным образом для zero_amount.

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

Ответы [ 7 ]

6 голосов
/ 26 декабря 2009

Вы действительно должны хранить / работать со значениями скидок в виде чисел, это значительно упростит сравнение.

1 голос
/ 26 декабря 2009

Вы пытались распечатать все значения?

<code><?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]);
?>

Поправка
Так что да, теперь, когда мы можем увидеть результат этого, кажется, что строка-купон представляет собой UTF16 (длиной 10 байт), а другая - что-то еще (длиной 5 байт).

(Проповедь следует.) Имея дело с деньгами, вы должны действительно позаботиться о том, чтобы числа обрабатывались правильно. Мы только что увидели, что строки подвергаются кодированию, и, как уже отмечали другие, плавающие объекты подвержены дробным ошибкам. Лучше всего попытаться выразить это в 1/100 с использованием целого числа и выразить валюту в отдельной переменной. (Проповедь закончена.)

Но я предполагаю, что coupon_amount -функция используется везде, и вы не можете ее изменить. Тогда вы можете захотеть преобразовать две строки в один и тот же формат. Взгляните на iconv .

1 голос
/ 26 декабря 2009

Есть много вещей, которые кажутся пользователю несущественными, но могут нарушить сравнение строк

  • coupon_amount () может вставить несколько пробелов в возвращаемое значение
  • coupon_amount () может возвращать переменное число нулей
  • coupon_amount () может использовать запятую вместо точки (в зависимости от локали)
  • coupon_amount () может кодировать знак фунта с использованием некоторой HTML-сущности

Сказал, что гораздо лучше сравнивать числовые значения, а затем форматировать число как валюту.

1 голос
/ 26 декабря 2009
<?php if(strcmp($coup_amount, $zero_amount)== 0) { ?>

Кажется очень нечитаемым по сравнению с:

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

Если coupon_amount () вернул фактическое значение, а не форматированное строковое представление.

Можете ли вы изменить функцию coupon_amount (), чтобы избавиться от символа фунта? функция php money_format хороша для добавления любого символа валюты пользователя в строку для отображения на странице (или того символа, для которого вы установили локаль)

В будущем вам придется сначала удалить символ фунта, прежде чем выполнять арифметику возвращаемого значения в coupon_amount ()

0 голосов
/ 07 августа 2013

Вы пытаетесь сравнить его без знака фунта? .. как это

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

Я вижу, что у вас проблемы с получением знака фунта, поэтому я думаю, что лучше всего попробовать это.

0 голосов
/ 27 декабря 2009

Абсурдные длины, на которые я должен был пойти, чтобы заставить это работать :) .. Я изменил первый, если оценка на:

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)) 
0 голосов
/ 26 декабря 2009

вызов strcmp выглядит нормально, моя ставка на функцию coupon_amount.

...