使用PHP比较$_POST中给出的字符串

4

我有一个表单,里面包含了物品的尺寸信息,我需要查看这些字符串是否相等,以便能够据此设置价格。然而当我试图这么做时,它提示这些字符串不相等,导致我无法得到价格。以下是我使用的代码:

if ($_POST['sizes'] == "Small ($30)"){$total = "30";}
if ($_POST['sizes'] == "Medium ($40)"){$total = "40";}
if ($_POST['sizes'] == "Large ($50)"){$total = "50";}
else {$total = $_POST['price'];}

我在这里做错了什么?我可以输出 $_POST['sizes'],它确实给了我其中的一个。

9个回答

8

Paul Dixon说的是正确的。我也建议使用switch语句,而不是那个笨重的if语句块(实际上其中有一个逻辑错误,我可以补充一下-当不是“大杯($50)”时,$total将始终等于$_POST['price'])。

<?php

switch ( $_POST['sizes'] )
{
    case 'Small ($30)' :
        $total = 30;
        break;
    case 'Medium ($40)' :
        $total = 40;
        break;
    case 'Large ($50)' :
        $total = 50;
        break;
    default:
        $total = $_POST['price'];
        break;
}

?>

@strager:这两个都不是bug,第二个甚至违反了Zend的编码规范。 - user42092
把默认情况放在最后是最佳实践,但不是绝对的。因此,技术上可能会有漏洞,但通常我认为在默认情况下使用break语句是多余的。 - Peter Bailey

3

这是一个很好的switch/case语句候选项,你的'else'可以作为默认情况。

此外,在Medium和Large上不使用elseif,如果您的$_POST ['sizes']不是Large,则$total将始终为$_POST ['price']。这也可能让您感到困惑。


2

所以,你知道,你的if/else存在问题,最后一个else总是会执行。使用switch仍然更好,但以下是你代码应该的样子:

if ($_POST['sizes'] == "Small ($30)") { $total = "30";
} else if ($_POST['sizes'] == "Medium ($40)") { $total = "40";
} else if ($_POST['sizes'] == "Large ($50)") { $total = "50";
} else { $total = $_POST['price']; }

对于那些说问题在于$30、$40等的人,实际上并不是这样。因为变量名不能以数字开头,所以PHP会忽略$40等。


你可能是对的。但是一般建议在不需要插值/转义序列时使用单引号,以避免解释器额外的工作。 - PhiLho
你说得没错,但解释器速度的差异是以毫秒为单位的,需要执行数百万次才能看到明显的影响。最大的区别在于编写带有HTML字符串并且必须转义所有双引号时。 - Darryl Hein

1

尝试使用单引号

if ($_POST['sizes'] == 'Small ($30)'){$total = "30";}
elseif ($_POST['sizes'] == 'Medium ($40)'){$total = "40";}
elseif ($_POST['sizes'] == 'Large ($50)'){$total = "50";}
else {$total = $_POST['price'];}

双引号字符串使用变量插值,因此$符号变得重要!请参见此PHP手册页面,了解在PHP中如何声明字符串字面量的差异。

(编辑以更正逻辑错误 - 如其他人所指出,使用switch会更清晰)


1

或者,比笨重的开关更好的是,您可以利用这个简单的逻辑并练习“数据驱动编程”:

$vals = array(
    'Small ($30)' => 30,
    'Medium ($40)' => 40,
    'Large ($50)' => 50
);

$total = array_key_exists($_POST['sizes'], $vals)
    ? $vals[$_POST['sizes']]
    : $_POST['price'];

看起来真的很漂亮和整洁,但我不确定它是如何工作的,所以我会坚持使用我知道的 switch 语句。 - helloandre
嘿,这没什么问题 - 无论你用什么方法都可以。不过,如果你确实想要解释,只需问一声 - 我很乐意帮忙。 - Bobby Jack

1

除了实际错误原因之外,如果您使用的是标签以外的其他值,例如:

<select name="sizes">
    <option value="small">Small ($30)</option>
    <option value="meduim">Medium ($40)</option>
    <option value="large">Large ($50)</option>
</select>

我给你点赞,但是“Small ($30)”有可能就是它的值了 ;) - Martijn Laarman
如果省略了VALUE属性,那么元素的内容实际上就是它的值。 ;) - Gumbo
我意识到,我开玩笑说有可能<option value="Small ($30)">非常小的衬衫!</option>是标记,因此OP对值标签的认识。 - Martijn Laarman
是的,我需要该值具体为处理订单。 - helloandre

0

$total是一个字符串吗?

$total = "30"; 是字符串的语法。$total = 30; 是数字的正确写法。


当涉及到POST请求时,它将是一个字符串。 - helloandre

0

这里不是有一个安全漏洞吗?如果有人只是提交他们想要的默认条款价格怎么办?


0
// remove any non-decimal characters from the front, then extract your value,
// then remove any trailing characters and cast to an integer
$total = (integer)preg_replace("/^\D*(\d+)\D.*/", "$1", $_POST['sizes']);
if (!$total) $total = $_POST['price'];

严谨一点说,第二个 \D 是不需要的。这假设 xxx(40) 应该是 40,而不是默认值(虽然这不是一个小问题)。 - Martijn Laarman
好的,问题是我需要Small (30)等尺寸来实际处理物品,因此剥离它并没有什么用处...否则我就直接输入30了。 - helloandre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接