Results: Which do you suggest? 

Voters
1 You may not vote on this poll

  • if()/elseif()
    0%
  • switch()
    100.00%
    #1
  1. No Profile Picture
    Super Moderator
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2009
    Location
    Hartford, WI
    Posts
    1,494
    Rep Power
    111

    switch() vs elseif()


    Hey all. I know the 2 are rather alike. I'm just looking for possible suggestions to pick one over the other before I finalize my structure in this area. I know the if()/elseif() lines can be truncated into a single line, so aside from that, are there preferences or suggestions between the two? If so, mind leaving your opinion? Thanks very much!
    PHP Code:
    <BODY>
      <DIV class="nav">
    <?= build_navigation(); ?>
      </DIV>
    <?php if($_SESSION['page'] == 'balance') { ?>
      <DIV class="balance">
    <?= build_balance($_SESSION['year']); ?>
      </DIV>
    <?php } elseif($_SESSION['page'] == 'paid_off') { ?>
      <DIV class="paid_off">
    <?= build_paid_off($_SESSION['year']); ?>
      </DIV>
    <?php } elseif($_SESSION['page'] == 'invoice') { ?>
      <DIV class="invoice">
    <?= build_invoice($_SESSION['year']); ?>
      </DIV>
    <?php } elseif($_SESSION['page'] == 'account') { ?>
      <DIV class="account">
    <?= build_account(); ?>
      </DIV>
    <?php ?>
    </BODY>
    PHP Code:
    <BODY>
    <?php
      
    echo '  <DIV class="nav">' "\n" build_navigation() . '  </DIV>' "\n";
      switch(
    $_SESSION['page']) {
        case 
    'balance': echo '    <DIV class="balance">' "\n" build_balance($_SESSION['year']) . '    </DIV>'; break;
        case 
    'paid_off': echo '    <DIV class="paid_off">' "\n" build_paid_off($_SESSION['year']) . '    </DIV>'; break;
        case 
    'invoice': echo '    <DIV class="invoice">' "\n" build_invoice($_SESSION['year']) . '    </DIV>'; break;
        case 
    'account': echo '    <DIV class="account">' "\n" build_account($_SESSION['year']) . '    </DIV>'; break;
      }
    ?>
    </BODY>
    Last edited by Triple_Nothing; October 8th, 2017 at 11:35 AM.
    He who knows not that he knows not is a fool, ignore him. He who knows that he knows not is ignorant, teach him. He who knows not that he knows is asleep, awaken him. He who knows that he knows is a leader, follow him.
  2. #2
  3. Lazy Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,380
    Rep Power
    9645
    I would have picked a place between those two:

    PHP Code:
    <body>
        <div class="nav">
            <?=build_navigation()?>
        </div>
    <?php switch ($_SESSION["page"]) { ?>
    <?php    
    case "balance"?>
        <div class="balance">
            <?=build_balance($_SESSION["year"])?>
        </div>
    <?php    case "paid_off"?>
        <div class="paid_off">
            <?=build_paid_off($_SESSION["year"])?>
        </div>
    <?php    case "invoice"?>
        <div class="invoice">
            <?=build_invoice($_SESSION["year"])?>
        </div>
    <?php    case "account"?>
        <div class="account">
            <?=build_account($_SESSION["year"])?>
        </div>
    <?php ?>
    </body>
    The main draw to switch here is reducing the amount of PHP in order to keep the syntax highlighting focused on the HTML.

    There's also a clever solution here that I probably wouldn't use:
    PHP Code:
    <body>
        <div class="nav">
            <?=build_navigation()?>
        </div>

    <?php if (in_array($_SESSION["page"], ["balance""paid_off""invoice""account"])) { ?>
        <div class="<?=$_SESSION["page"]?>">
            <?=call_user_func("build_" $_SESSION["page"], $_SESSION["year"])?>
        </div>
    <?php ?>
    </body>
    PHP Code:
    <?= /* or with PHP 7 */ ("build_" $_SESSION["page"])($_SESSION["year"]) ?>
    I wouldn't because I dislike anything that breaks my IDEs ability to identify where symbols, like functions, are used in code (with some exceptions that this code doesn't use). It also depends on the coincidence (?) that the "page" value matches the corresponding build_* function name, and either could/should be able to change without relying on the value of the other.
    Last edited by requinix; October 8th, 2017 at 11:52 AM.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2016
    Posts
    99
    Rep Power
    50
    The answer is to use neither in this case (programming pun intended.)

    If all you are doing is mapping input values to different output values, or what you are actually doing is validating input data before using it, you would use a data-driven design and store the permitted values in a data structure, such as an array or a database table, then write general purpose code that uses the data structure to tell it what to do -

    PHP Code:
    $permitted_pages = array('balance''paid_off''invoice''account');

    $page = isset($_SESSION['page']) && in_array($_SESSION['page'],$permitted_pages) ? $_SESSION['page'] : false// if you want a default value if the session isn't set or it's not one of the values, change the false to that value

    if(!$page)
    {
        echo 
    "not a valid page";
    }
    else
    {
        
    $func "'build_$page";
        echo 
    '<DIV class="$page">' "\n" $func($_SESSION['year']) . '</DIV>'

    By using a data-driven general purpose design, you can now add, remove, or change any of the pages, simply by changing the defining data, which you can store in a configuration file or query from a database table. You don't have to touch any of the program logic.

    I'm also betting that the four different build_xxxxx() functions are mostly coded the same, only operating on different data? If so, rather than to repeat the same coding in them, just use one function and pass it the page value and have it use that to determine what data to operate on.
  6. #4
  7. No Profile Picture
    Super Moderator
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2009
    Location
    Hartford, WI
    Posts
    1,494
    Rep Power
    111
    As y'all have provided suggestions, they whole $permitted_pages does provide a simple way to add the else/default action/value. The functions are nothing alike in this manner. I just have the page name and build_* matching for the sake of easy referencing.

    So instead of the if()/elseif() or switch() longer list, it sounds the suggestion is simply have a 'valid pages' array defined, and run the same <DIV>' . build_$page() . '</DIV> that I'm just repeating in my options... ^_^

    Edit: I suppose this is a bit more the way I should swing. It is a bit shorter/simpler, so hopefully I got it right. I know the array itself can be built, so the one here is more for the overall example. $_SESSION['page/year'] is set prior, even to a default if no $_GET
    PHP Code:
    <BODY>
      <DIV class="nav">
    <?= build_navigation(); ?>
      </DIV>
    <?php
      
    if(in_array($_SESSION['page'], ['balance', 'paid_off', 'invoice', 'account'])) {
        echo 
    '<DIV>' call_user_func('build_' . $_SESSION['page'], $_SESSION['year']) . '</DIV>';
      } else {
        echo 
    '<DIV>' build_error('invalid_page') . '</DIV>';
      }
    ?>
    </BODY>
    In Read-Only mode, currently using if()/elseif()'s: Bills (2017)
    Last edited by Triple_Nothing; October 8th, 2017 at 12:33 PM.
    He who knows not that he knows not is a fool, ignore him. He who knows that he knows not is ignorant, teach him. He who knows not that he knows is asleep, awaken him. He who knows that he knows is a leader, follow him.
  8. #5
  9. No Profile Picture
    Super Moderator
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2009
    Location
    Hartford, WI
    Posts
    1,494
    Rep Power
    111
    Just switched over to the "Valid Pages" idea, so I hope this looks good!
    PHP Code:
    <?php
      session_start
    ();
      
    $_SESSION['mode'] = isset($_GET['mode']) ? $_GET['mode'] : (isset($_SESSION['mode']) ? $_SESSION['mode'] : 'read');
      
    $_SESSION['page'] = isset($_GET['page']) ? $_GET['page'] : (isset($_SESSION['page']) ? $_SESSION['page'] : 'invoice');
      
    $_SESSION['year'] = isset($_GET['year']) ? $_GET['year'] : (isset($_SESSION['year']) ? $_SESSION['year'] : date('Y'));
      include(
    './inc/db.inc');
      include(
    './inc/functions.inc');
    ?><!DOCTYPE HTML>
    <HTML>
      <HEAD>
        <META http-equiv="content-type" content="text/html; charset=utf-8" />
        <META name="generator" content="PSPad editor, www.pspad.com" />
        <TITLE>Bills (<?= $_SESSION['year']; ?>)</TITLE>
        <LINK href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css" rel="stylesheet">
        <LINK href="./css/nav_menu.css" rel="stylesheet" type="text/css" />
        <LINK href="./css/general.css" rel="stylesheet" type="text/css" />
        <LINK href="./css/<?= $_SESSION['page']; ?>.css" rel="stylesheet" type="text/css" />
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
        <script src="./js/functions.js" type="text/javascript"></script>
      </HEAD>
      <BODY>
        <DIV class="nav">
    <?= build_navigation(); ?>
        </DIV>
    <?php
      
    if(in_array($_SESSION['page'], ['balance''paid_off''invoice''account''updates'])) {
        echo 
    '<DIV class="' $_SESSION['page'] . '">' call_user_func('build_' $_SESSION['page'], $_SESSION['year']) . '</DIV>';
      } else {
        echo 
    '<H1>Invalid page.</H1>';
      }
    ?>
      </BODY>
    </HTML>
    He who knows not that he knows not is a fool, ignore him. He who knows that he knows not is ignorant, teach him. He who knows not that he knows is asleep, awaken him. He who knows that he knows is a leader, follow him.
  10. #6
  11. Lazy Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,380
    Rep Power
    9645
    I actually prefer DSmabismad's approach using $permitted_pages, but with a slight variation.
    PHP Code:
    $permitted_pages = array(
        
    "balance" => "build_balance",
        
    "paid_off" => "build_paid_off",
        
    "invoice" => "build_invoice",
        
    "account" => "build_account"
    ); 
    and
    PHP Code:
    if (isset($permitted_pages[$_SESSION["page"]])) {
        ...
        
    $permitted_pages[$_SESSION["page"]]($_SESSION["year"]);
        ...

    It avoids the problem of building function names (you can search for "build_paid_off" to see usage) while keeping the callback-style flexibility.

    Comments on this post

    • Triple_Nothing agrees : Nice.
  12. #7
  13. No Profile Picture
    Super Moderator
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2009
    Location
    Hartford, WI
    Posts
    1,494
    Rep Power
    111
    Just wondering if anyone has suggestions for/against my alteration? I know the 'short-hand' line is a bit long, but wondering if the idea has much any downsides...
    index.php
    PHP Code:
      <BODY>
    <?php
      
    echo (isset($page_builds[$_SESSION['page']])) ? "    <DIV class=\"" $_SESSION['page'] . "\">\n" $page_builds[$_SESSION['page']]($_SESSION['year']) . "    </DIV>\n" "    <H1>Invalid page.</H1>";
    ?>
      </BODY>
    Near beginning of functions.inc
    PHP Code:
    $page_builds = array(
      
    'account' => 'build_account',
      
    'balance' => 'build_balance',
      
    'invoice' => 'build_invoice',
      
    'paid_off' => 'build_paid_off',
      
    'updates' => 'build_updates'
    ); 
    Edit: Navigation build/echo removed since that's not really the topic.
    Last edited by Triple_Nothing; October 12th, 2017 at 05:54 PM.
    He who knows not that he knows not is a fool, ignore him. He who knows that he knows not is ignorant, teach him. He who knows not that he knows is asleep, awaken him. He who knows that he knows is a leader, follow him.
  14. #8
  15. Lazy Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,380
    Rep Power
    9645
    Seems fine to me. Personally I prefer reducing the amount of HTML in strings (see my first post) but performance-wise it probably doesn't matter enough to be an issue.
  16. #9
  17. Banned (not really)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 1999
    Location
    Caro, Michigan
    Posts
    14,793
    Rep Power
    4536
    Anytime you have to echo HTML, you're doing it wrong in my opinion.
    -- Cigars, whiskey and wild, wild women. --
  18. #10
  19. No Profile Picture
    Super Moderator
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2009
    Location
    Hartford, WI
    Posts
    1,494
    Rep Power
    111
    To avoid the echo-ing HTML remarks, does this code suffice? I move my isset() to the upper part of my code checking/setting my $_SESSION variables. Then just used the variable as needed in the build. This keeps the HTML out on its own, so I think, and instead of my initial thought of an "error/invalid" type page, it will just leave them at the current page, or if defined at first, default to the initial default page of 'invoice'.
    Before my <!DOCTYPE>:
    PHP Code:
    $_SESSION['page'] = isset($_GET['page'], $page_builds[$_GET['page']]) ? $_GET['page'] : (isset($_SESSION['page']) ? $_SESSION['page'] : 'invoice'); 
    And the <BODY>:
    PHP Code:
      <BODY>
        <DIV class="nav">
    <?= build_navigation(); ?>
        </DIV>
        <DIV class="<?= $_SESSION['page']; ?>">
    <?= $page_builds[$_SESSION['page']]($_SESSION['year']); ?>
        </DIV>
      </BODY>
    Last edited by Triple_Nothing; October 12th, 2017 at 06:33 PM.
    He who knows not that he knows not is a fool, ignore him. He who knows that he knows not is ignorant, teach him. He who knows not that he knows is asleep, awaken him. He who knows that he knows is a leader, follow him.
  20. #11
  21. Lazy Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,380
    Rep Power
    9645
    If you're doing
    PHP Code:
    $_SESSION['page'] = isset($_GET['page'], $page_builds[$_GET['page']]) ? $_GET['page'] : (isset($_SESSION['page']) ? $_SESSION['page'] : 'invoice'); 
    then does the value really need to be in the session? Seems like it should be just a regular variable.

    And yeah, that's the style I prefer. Use what makes most sense to you.
  22. #12
  23. No Profile Picture
    Super Moderator
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2009
    Location
    Hartford, WI
    Posts
    1,494
    Rep Power
    111
    Well, what ends up in the $_GET may not always be the initial arrival/defining of the page. Since most is really charts, a main item that may just make a swap of the builds would be a change in the selected year. That would add just ?year=YYYY to the address, and $_SESSION would be used as a way to stay on the current page, and just adjust that item. As my full code a few posts up define, most my entire site is decided among 3 things... Mode/Page/Year with the $_SESSION, each can be altered independently, such as changing the years, or switching between Read/Edit mode on the currently viewed page.
    He who knows not that he knows not is a fool, ignore him. He who knows that he knows not is ignorant, teach him. He who knows not that he knows is asleep, awaken him. He who knows that he knows is a leader, follow him.
  24. #13
  25. Wiser? Not exactly.
    Devshed God 2nd Plane (6000 - 6499 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    6,098
    Rep Power
    4103
    I would split the code up a bit more, and maybe define a shorter variable name, mainly because I dislike nested ternary operators and long lines.
    Code:
    <?php
    
    
    $page = isset($_SESSION['page'])?$_SESSION['page']:null;
    $page = isset($_GET['page'])?$_GET['page']:null;
    $page = isset($page_builds[$page])?$page:'invoice';
    
    
    $_SESSION['page'] = $page;
    
    
    $page_builds[$page]($_SESSION['year']);
    If using PHP 7 or higher, the first bit could instead be
    Code:
    $page = $_GET['page'] ?? $_SESSION['page'] ?? 'invoice';
    $page = isset($page_builds[$page])?$page:'invoice';
    Nothing really wrong with what you have though. To each their own.
    Recycle your old CD's



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud
  26. #14
  27. No Profile Picture
    Super Moderator
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2009
    Location
    Hartford, WI
    Posts
    1,494
    Rep Power
    111
    I am on PHP 7, and I know it has a fair amount of changes. How exactly is the code below functioning with the double ??'s
    PHP Code:
    $page $_GET['page'] ?? $_SESSION['page'] ?? 'invoice'
    Edit: Ah, found an example. First true value is used...

    Is there a limit of options, or could we have like 10 items separated by ??'s, and the first true would just be used?

    If all items were variables, and none existed, would that error, or just be passed over?
    Last edited by Triple_Nothing; October 13th, 2017 at 02:03 PM.
    He who knows not that he knows not is a fool, ignore him. He who knows that he knows not is ignorant, teach him. He who knows not that he knows is asleep, awaken him. He who knows that he knows is a leader, follow him.
  28. #15
  29. Wiser? Not exactly.
    Devshed God 2nd Plane (6000 - 6499 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    6,098
    Rep Power
    4103
    Originally Posted by Triple_Nothing
    Edit: Ah, found an example. First true value is used...
    It's the Null Coalescing Operator. It returns the first value that is not null. It'll return a false value if it exists, so long as it is not null.

    For example:
    Code:
    $b = false;
    $c = null;
    $d = 'Yep';
    
    $result = $a ?? $b ?? $c ?? $d;
    $result2 = $a ?? $c ?? $d;
    var_dump($result, $result2);
    
    // $result = bool(false)
    // $result2 = string('Yep')
    There's no limit on how many items you can test, or at least none that you'd ever reach. I'd suggest if you ever find yourself testing more than a handful of variables you probably need to be doing something different.
    Recycle your old CD's



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud

IMN logo majestic logo threadwatch logo seochat tools logo