S
S
Sergey Brovko2015-11-12 00:28:53
PHP
Sergey Brovko, 2015-11-12 00:28:53

How to implement multiple conditions?

Please tell me about the following question:
There is a script that works with the database, the result of the work depends on the accepted (POST) parameters (parameter-value) There
are several parameters, some depend on others (if the parameter is N1, then also check the parameters N2, N3, if the parameter N2, then check the parameters N5, N10 (for example)).
Values ​​of some parameters can only take certain values, otherwise an error occurs.
I made the script, it works, but it will turn out to be a miserable crutch with a bunch of ifs and elses, it’s most disgusting to watch.
Actually a question how it is possible to implement check of the entering data on compliance to the necessary conditions without a heap of if`ov?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sergey, 2015-11-12
@cyber01

So... let's take your code

if (!preg_match("/^[a-zA-Z0-9_]+$/", $username)) die("Bad login");
        if (
        $type != 'voice' and $type != 'balance1' and $type != 'balance2' and $type != 'absvoice' and $type != 'passhash' and
        $type != 'paytime' and $type != 'white1' and $type != 'exp1' and $type != 'white2' and $type != 'voice2' and
        $type != 'exp2') die("Wrong type");
        if ($action != 'set' and $action != 'get' and $action != 'add') die("Wrong action");
        if ($action == 'set' and !(preg_match("/^[0-9-.]+$/", $value)) and $type != 'passhash') die("Wrong value");
        if (($action == 'set' or $action == 'add') and ($type == 'paytime' OR $type == 'absvoice')) die("paytime/absvoice read only");
        if (($action == 'add') and ($type == 'passhash' or $type == 'white1' or $type == 'white2')) die("add not available for this");

the first thing we can see here is the duplication of conditions, we have a lot of approximately the same conditions. Let's simplify things using in_array
if (!preg_match("/^[a-zA-Z0-9_]+$/", $username)) die("Bad login");

$availableTypes = ['voice', 'balance1', 'balance2', 'absvoice', 'passhash', 'paytime', 'white1', 'exp1', 'white2', 'voice2', 'exp2'];
if (!in_array($type, $availableTypes)) {
    die("Wrong type");
}

if (!in_array($action, ['set', 'get', 'add'])) {
    die("Wrong action");
}
if ($action == 'set' and !(preg_match("/^[0-9-.]+$/", $value)) and $type != 'passhash') {
    die("Wrong value");
}
if (($action == 'set' or $action == 'add') and in_array($type, ['paytime', 'absvoice'])) {
    die("paytime/absvoice read only");
}
if (($action == 'add') and (in_array($type, ['passhash', 'white1', 'white2']))) {
    die("add not available for this");
}

now we could calm down, because further we have differences in what happens according to the conditions. So there is no further duplication as such.
Next, we can put these rules into an array, and then get rid of ifs altogether, since we replace them with an array of rules for each action. But everything messes up the regular expression for set, I have a suspicion that ... it is not true.
updated: get rid of all ifs (more precisely, replace with one)
$constraints = [
    'unsupportedTypes' => !in_array($type, $availableTypes),
    'unsupportedAction' => !in_array($action, ['set', 'get', 'add']),
    'expectedNumericValue' => $action == 'set' && is_numeric($value),
    'readOnlyType' => 'get' !== $action && in_array($type, ['paytime', 'absvoice']),
    'disallowedTypes' => 'add' === $action && in_array($type, ['passhash', 'white1', 'white2']),
];

$constraintsMessages = [
    'unsupportedTypes' => 'Type "<type>" is not supported',
    'unsupportedAction' => 'Action "<action>" is not supported',
    'expectedNumericValue' => 'Wrong value, expected numeric',
    'readOnlyType' => '<type> is read only',
    'disallowedTypes' => 'Type "<type>" is not supported for action "<action>"'
];

$errors = array_keys(array_filter($constraints));
if (!empty($errors)) {

    die(str_replace(
        ['<type>', '<action>'],
        [$type, $action],
        $constraintsMessages[reset($errors)]
    ));
}

this business can be further simplified and build normal validation rules + a separate function that will check the whole thing.

A
Alexander Latyshev, 2015-11-12
@magalex

As an option, use the in_array function and make conditions 2 and 3 like this:

if( !in_array( $type, ['voice', 'balance1', 'balance2', ...] ) ) die("Wrong type");
if( !in_array( $action, ['set', 'get', 'add'] ) ) die("Wrong action");

construction
replaced by
replace the rest in the same way

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question