If-else statement for 5 Conditions in PHP

Viewed 66

I have a scenario where I have to match all possible conditions for 5 variables with the if-else statement, the value of variables can be either 0 or 1, for example

if($a === 0 && $b === 0 && $c === 0 && $d === 0 && $e === 0) { 
    echo 'case_1';
} else if ($a === 1 && $b === 1 && $c === 1 && $d === 1 && $e === 1) {
    echo 'case_2';
} else if ($a === 0 && $b === 1 && $c === 1 && $d === 1 && $e === 1) {
    echo 'case_3';
} else if ($a === 0 && $b === 0 && $c === 1 && $d === 1 && $e === 1) {
    echo 'case_4';
} else if ($a === 0 && $b === 0 && $c === 0 && $d === 1 && $e === 1) {
    echo 'case_5';
} else if ($a === 0 && $b === 0 && $c === 0 && $d === 0 && $e === 1) {
    echo 'case_6';
} else if ($a === 1 && $b === 0 && $c === 0 && $d === 0 && $e === 0) {
    echo 'case_7';
} 

----
----

There could be dozens of such conditions and managing it becomes complicated, so I want to know if there is any better and robust method to achieve this?

Update:

Variables could be alphanumeric as well,

$none = 'none'; // Default value

if($a === $none && $b === $none && $c === $none && $d === $none && $e === $none) { 
    echo 'case_1';
} else if ($a === 1 && $b === 1 && $c === 1 && $d === 1 && $e === 1) {
    echo 'case_2';
} else if ($a === $none && $b === 1 && $c === 1 && $d === 1 && $e === 1) {
    echo 'case_3';
} else if ($a === $none && $b === $none && $c === 1 && $d === 1 && $e === 1) {
    echo 'case_4';
} else if ($a === $none && $b === $none && $c === $none && $d === 1 && $e === 1) {
    echo 'case_5';
} else if ($a === $none && $b === $none && $c === $none && $d === $none && $e === 1) {
    echo 'case_6';
} else if ($a === 1 && $b === $none && $c === $none && $d === $none && $e === $none) {
    echo 'case_7';
} 

------
------
3 Answers

I'm trying to think of a slicker way, but for now; you can combine the variables into a string and check:

switch($a.$b.$c.$d.$e) {
    case '11111':
        echo 'case_1';
        break;
        
    case '00000':
        echo 'case_2';
        break;
        
    //etc...
}

As for your edit, just use variables in the cases:

    case $none.$none.$none.$none.$none:
    //or 
    case $none.'1111':
    //etc

For the moment, I can only tell you the existence of the match expression, but is available only in PHP8:

$case = match($a.$b.$c.$d.$e) {
    '00000' => 'case_0',
    '11111' => 'case_1',
    ...
    // default => something,
};

That is just a "smaller" switch

Well without understanding, what your particular use case is, just that you want to check what essentially equates some sort of encoded state... I took the liberty to demonstrate a fully demonstrated use case.

at the heart of this example is this parseCrumbs function, who's abstract would be something like this...


    function parseCrumbs($crumbs, $tranformer,  $text = '')  {

        // provide a list of methods, to carry out some sort of tranformation, based on positions
        static $places = ['negative', 'thousands', 'hundreds', 'tens', 'ones'];

        if(is_string($crumbs)) 
            $crumbs = str_split($crumbs, 1);

        // Reduce $crumns through transformations...
        foreach ( array_combine( $places, $crumbs ) as $method => $value ){
            if($value) $text .= " " . $tranformer::$method($value, $text);
        }

        return  $text === '' ? '-- empty --' : $text . PHP_EOL;

    }

Demonstration of mock use case: Transform a 5 position state string to representing the total count in words...


    class Transformations {

        static public function ones ($count, &$text ) {
            if($count)
                return ($text === '' || $text !== 'Minus ') ? "( {$count} ) Ones" : "and ( {$count} ) Ones";
            return '';
        }

        static public function tens ($count, &$text ) {
            if($count)
                return "( {$count} ) Tens";
            return '';
        }

        static public function hundreds ($count, &$text ) {
            if($count)
                return "( {$count} ) Hundreds";
            return '';
        }

        static public function thousands ($count, &$text ) {
            if($count)
                return "( {$count} ) Thousands";
            return '';
        }

        static public function negative ($count, &$text ) {
            if($count)
                return  'Minus';
            return '';
        }
    }

    function parseCrumbs($crumbs, $translations,  $text = '')  {
        static $places = ['negative', 'thousands', 'hundreds', 'tens', 'ones'];

        if(is_string($crumbs)) 
            $crumbs = str_split($crumbs, 1);

        foreach ( array_combine($places, $crumbs ) as $method => $value ){
            if($value) $text .= " " . $translations::$method($value, $text);
        }

        return  $text === '' ? '-- you need money --' : $text . PHP_EOL;

    }

    // These examples use a String to encode the state, 
    // but the parseCrumbs function can also accept an array...

    echo parseCrumbs('00001', Transformations::class); // ( 1 ) Ones
    echo parseCrumbs('00011', Transformations::class); // ( 1 ) Tens ( 1 ) Ones
    echo parseCrumbs('00111', Transformations::class); // ( 1 ) Hundreds ( 1 ) Tens ( 1 ) Ones
    echo parseCrumbs('00111', Transformations::class); // ( 1 ) Hundreds ( 1 ) Tens ( 1 ) Ones
    echo parseCrumbs('01111', Transformations::class); // ( 1 ) Thousands ( 1 ) Hundreds ( 1 ) Tens ( 1 ) Ones
    echo parseCrumbs('10001', Transformations::class); // Minus ( 1 ) Ones
    echo parseCrumbs('10011', Transformations::class); // Minus ( 1 ) Tens ( 1 ) Ones
    echo parseCrumbs('10111', Transformations::class); // Minus ( 1 ) Hundreds ( 1 ) Tens ( 1 ) Ones
    echo parseCrumbs('10111', Transformations::class); // Minus ( 1 ) Hundreds ( 1 ) Tens ( 1 ) Ones
    echo parseCrumbs('11111', Transformations::class); // Minus ( 1 ) Thousands ( 1 ) Hundreds ( 1 ) Tens ( 1 ) Ones

To demonstrate the permutations...

    for( $i = 5000; $i > 0; $i--)
        echo parseCrumbs(str_pad($i, 5, "0", STR_PAD_LEFT), Transformations::class);


    // ( 5 ) Thousands
    // ( 4 ) Thousands ( 9 ) Hundreds ( 9 ) Tens and ( 9 ) Ones
    // ( 4 ) Thousands ( 9 ) Hundreds ( 9 ) Tens and ( 8 ) Ones
    // ... 4996 other permutations
    // ( 1 ) Ones

When modeled as above, with ~49 lines of code, depending on your transformations... you have the logic to handle 5000 states...

Obviously your use case, would require customizations, but the "logic" would probably remain just as simple and clear.


After reviewing you comments above, I whipped together an example, with an array similar to checkbox type inputs...

    class ShirtOptions {

        public function __construct(){
            $this->options = (object)[];
        }

        public function x_large ( $state ) {
            if ($state) $this->options->shirt_size = "x_large";
        }

        public function xx_large ( $state ) {
            if ($state) $this->options->shirt_size = "xx_large";
        }

        public function xxx_large ( $state ) {
            if ($state) $this->options->shirt_size = "xxx_large";
        }

        public function small ( $state ) {
            if ($state) $this->options->shirt_size = "small";
        }

        public function customPrinting ( $state ) {
            if($state){
                $this->options->custom_printing = true;
            } else {
                $this->options->custom_printing = false;
            }
        }

        public function templateID ( $state ) {
            if($state){
                $this->options->template_id = $state;
            }
        }

        public function parseOptions( $params ){
            static $options = [ "x_large", "xx_large", "xxx_large", "small", "customPrinting", "templateID" ];

            if(is_string($params))
                $params = str_split($params, 1);

            foreach ( array_combine( $options, $params ) as $option => $value )
                if($value) $this->$option($value);

            return $this;
        }

        public function to_json(){
            return json_encode($this->options, JSON_PRETTY_PRINT);
        }
    }

        

    echo (new ShirtOptions())->parseOptions([1,0,0,0,1,475])->to_json();
    {
        "shirt_size": "x_large",
        "custom_printing": true,
        "template_id": 475
    }

Related