Reputation: 73
I'm creating a basic form to purchase adult & child tickets from. With the way the form is set up, the user must purchase an adult ticket, but they don't need to purchase a child ticket. I've added some error messages/validations to enforce rules within the form. All of the adult ticket error messages work correctly, but the child ones aren't working right.
I want the child ticket rules to check the following: that a valid number (aka not a letter) has been entered, the quantity is greater than 0, and a whole number has been entered. I thought I had the rules set so they only start validating if the child ticket input is not empty, but instead they're still trying to validate when it is empty, which I don't want it to do considering no child tickets need to be purchased. How do I get this to work correctly?
Here is my PHP code with the error messages.
<?php
$adult=$_POST['adult'];
$child=$_POST['child'];
$date=date('m/d/Y');
function isInteger($input) {
return(ctype_digit(strval($input)));
}
if (empty($adult)) {
$error_message='You must purchase at least 1 Adult ticket!';
}
else if (!is_numeric($adult)) {
$error_message="You must enter a valid number!";
}
else if ($adult <= 0) {
$error_message="You must enter a quantity greater than zero!";
}
else if (!isInteger($adult)) {
$error_message="You must enter a whole number for the quantity! (i.e. 1, 2, etc...)";
}
else if (!empty(!is_numeric($child))) {
$error_message="You must enter a valid number!";
}
else if (!empty($child <= 0)) {
$error_message="You must enter a quantity greater than zero!";
}
else if (!empty(!isInteger($child))) {
$error_message="You must enter a whole number for the quantity! (i.e. 1, 2, etc...)";
}
else if ($adult + $child > 5) {
$error_message="Sorry, there is a limit of 5 total tickets per customer!";
}
else {
$error_message='';
}
if($error_message !=""){
include('index.php');
exit();
}
?>
Upvotes: 1
Views: 66
Reputation: 18426
Not looking for an accepted answer, just wanted to suggest a more practical approach.
PHP has some very powerful built-in functions for validation. Two you can use are filter_var
and filter_input
, which can easily validate numeric values as integers, without needing to check each variation of an integer.
Additionally instead of chaining several elseif
conditions, I suggest using throw
to immediately raise an Exception that needs to be handled, otherwise halting execution at that point. Accompanied within a try/catch
block to handle the exception as desired.
$adult = filter_var($_POST['adult'] ?? null, FILTER_VALIDATE_INT);
$child = filter_var($_POST['child'] ?? null, FILTER_VALIDATE_INT);
try {
if (false === $adult || false === $child) {
throw new \InvalidArgumentException('You must enter a whole number (1, 2, etc...)');
}
if (0 >= $child || 0 >= $adult) {
throw new \InvalidArgumentException('You must enter a quantity greater than zero!');
}
// at this point child and adult must be >= 1
// ensure total is at least 1 and at most 5
$total_options = ['options' => ['min_range' => 1, 'max_range' => 5]];
$total = filter_var($adult + $child, FILTER_VALIDATE_INT, $total_options);
if (false === $total) {
throw new \InvalidArgumentException('Sorry, there is a limit of 5 total tickets per customer!');
}
// what should happen next...
} catch(\InvalidArgumentException $e) {
$error_message = $e->getMessage();
require __DIR__ . '/index.php';
## always use absolute paths to prevent include_path overrides/overhead
} finally {
// do something else no regardless of success or Exception...
}
For PHP < 7.0 replace
$_POST['child']) ?? null
with
isset($_POST['child']) ? $_POST['child'] : null
Upvotes: 0
Reputation: 5796
If $child = 1
if(!empty($child <= 0) )
is equivalent to if(!empty(false))
which makes no sense.
Same with (!empty(!is_numeric($child)))
Use if(isset($child) && $child <= 0) {}
instead
You can also use $child = isset($_POST['child']) ? $_POST['child'] : 0
Upvotes: 3