Search code examples
phpif-statementswitch-statementternary

Efficient/Non-Redundant way to Set variable in PHP with Switch, If, or Ternary


What is the best way to set a single variable when having multiple checks? There must be some efficient, precise, non-redundant, readable way to do this?

I rarely use Switch statements as I find them very redundant, often taking up 3-4 lines per check where you can often get away with a simple 1-2 line check, which adds up as you do more checks.

I was just reading that Switch statements are more readable compared to if/elseif/else blocks, and I can see how it is more readable due to alignment.

I enjoy using ternary statements because it allows you to use a single variable declaration, rather than writing redundant code, but a switch statement to me seems overly redundant plus its code(line consumption) overhead.

Hacked In Enum

class eUserType
{
    const Normal = 0;
    const Admin = 1;
    const Moderator = 2;
}

if elseif if

if ($userType == eUserType::Normal)
    $info = "Normal User";
elseif($userType == eUserType::Admin)
    $info = "Admin User";
elseif($userType == eUserType::Moderator)
    $info = "Moderator User";
else
    $info = false;

switch

switch($userType)
{
    case eUserType::Normal:
        $info = "Normal User";
        break;
    case eUserType::Admin:
        $info = "Admin User";
        break;
    case eUserType::Moderator:
        $info = "Moderator User";
        break;
    default:
        $info = false;
}

Ternary

I have never written a Ternary like this before, and went with my own whitespacing on it. It seems precise and efficient but I still find this to be very redundant with: "$userType == eUserType::". Plus I'm assuming most IDE's aren't going to handle the auto indent of code very well with this, as mine didn't (PHPStorm).

$info = $userType == eUserType::Normal ? 
            "Normal User" : 
        $userType == eUserType::Admin ? 
            "Admin User" : 
        $userType == eUserType::Moderator ? 
            "Moderator User" : false; 

I assume that I should be wrapping this into a function/method return the $info and not care what lies inside the function?

I'm wondering if there's some great way to do something like this that I haven't yet seen yet.

Ultimately what I think I'm looking for is a hybrid of Ternary's single variable setting with a switch statement's single variable check. (Doubtful it exists, but why not ask?)

Edit: I know that there's surely a way to use reflection to make this code dynamic if following a rigid pattern, but I used the data being set to $info as simple example data rather than the complex objects I'm working with. I'm thinking I'll end up tossing these checks into the User Class for any possible reusability.


Solution

  • How about using an array?

    $labels = array(
      eUserType::Normal => "Normal User",
      ...
    );
    
    return isset($labels[$userType]) ? $labels[$userType] : false;
    

    Yeah, it's possible with Reflection too (I wouldn't go this way though, you can't localize your strings this way):

    $class = new ReflectionClass('eUserType');
    $key   = array_search($userType, $class->getConstants());
    
    return ($key !== false) ? sprintf('%s User', $key) : false;