tags:

views:

1183

answers:

9

I have a form that is sending in sizes of things, and I need to see what the strings are equal to so that I can set the price accordingly. When i try to do this, it says that they are not equal, and i get no prices. This is the code i'm using:

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'];}

What am i doing wrong here? I can echo $_POST['sizes'] and it gives me exactly one of those things.

+1  A: 

Try using single quotes

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'];}

Double quoted strings use variable interpolation, so the $ symbol becomes significant! See this manual page for the differences in how you can declare string literals in PHP.

(Edited to correct the logic error - as others noted, a switch would be much clearer here)

Paul Dixon
+7  A: 

What Paul Dixon said is correct. Might I also recommend using a switch statement instead of that clunky chunk of if statements (which actually has a logic bug in it, I might add - $total will always equal $_POST['price'] when not 'Large ($50)')

<?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;
}

?>
Peter Bailey
Great Bailey's think alike!
Adam
Fixed a possible bug. Hope you don't mind.
strager
@strager: Neither of those are bugs, and the second one is even against Zend's coding standards.
Ant P.
Well, putting the default case at the bottom is is a best-practice, but not an absolute. So yes, technically there could be a bug here, but generally I consider break statements in the default to be superfluous.
Peter Bailey
+3  A: 

That's a good candidate for a switch/case statement, with your 'else' being a default.

Also, without using elseif's on Medium and Large, if your $_POST['sizes'] is not Large, then your $total will always be $_POST['price']. This could be throwing you off as well.

Adam
+2  A: 

So you know, the problem with your if/else's is that the last else is always happening. A switch is still better, but here is what your code should be:

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']; }

To everyone that says the problem is the $30, $40, etc, it's not. Variables can't start with a number so PHP will ignore the $40, etc.

Darryl Hein
You are probably right. Still general advice is to use single quotes when you don't need interpolation/escape sequences, to avoid extra work from the interpreter.
PhiLho
You are right, but the difference in speed for the interpreter is ms over millions of reps. The biggest difference is when writing strings with HTML in them and having to escape all the double quotes.
Darryl Hein
A: 

Is $total a string?

$total = "30"; is the syntax for a string. $total = 30; would be correct for Numeric.

well, when it comes from a POST, it would be a string.
contagious
A: 

Isn't there a security hole here? What if someone just submits whatever price they want for the default clause?

Chris KL
+1  A: 

Or, even better than the clunky switch, you can take advantage of this simple logic and practise 'data-driven programming':

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

$total = array_key_exists($_POST['sizes'], $vals)
    ? $vals[$_POST['sizes']]
    : $_POST['price'];
Bobby Jack
that looks really nifty and neat, but i'm not sure exactly how it works, so i'll stick with the switch statement that i know
contagious
Hey, nothing wrong with that - whatever works for you. If you DO want an explanation, though, just ask - I'd be happy to oblige.
Bobby Jack
A: 
// 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'];
eplawless
total nitpick: the 2nd \D isnt needed. this assumes xxx(40) should be 40 and not the default though which is not a nitpick.
Martijn Laarman
well, the thing was i needed the Small (30), etc for the actual processing of the item, so stripping it wouldn't really be useful...otherwise i'd just enter 30.
contagious
+1  A: 

Apart from the actual cause of this error, it could have been avoided if you had used other values than the labels, e.g.:

<select name="sizes">
    <option value="small">Small ($30)</option>
    <option value="meduim">Medium ($40)</option>
    <option value="large">Large ($50)</option>
</select>
Gumbo
+1 from me but there could always be the posibility `Small ($30)` **is** the value ;)
Martijn Laarman
If the VALUE attribute is obmitted, the element content actually IS the value. ;)
Gumbo
i realize, i was joking that there is a chance <option value="Small ($30)">Really Small Shirt!</option> is the markup and thus the OP awareness on the value tag.
Martijn Laarman
ya, i needed value to be that specifically for processing an order.
contagious