简体   繁体   中英

How can I make these PHP if statements more succinct?

I have multiple if statements which almost do the same thing. Only the number will change. I have shown only two ifs below. There will always be at least one button but there could be up to twenty, so I would like to know how I can make this more succinct.

       if (isset($_POST['button1']) && ($_POST['button1']) == $button1 ){
        $stmt = $db->prepare('UPDATE members SET page = :page WHERE memberid = :memberid');
        $stmt->execute(array(':memberid' => $_SESSION['memberID'], ':page' => $_POST['button1']));
        $array = $stmt -> fetchAll(PDO::FETCH_ASSOC);
        $_SESSION["page"] = $_POST['button1'];
        header ('Location: memberpage.php?page=' . $_SESSION["page"]);
}
elseif (isset($_POST['button2']) && ($_POST['button2']) == $button2 ){
        $stmt = $db->prepare('UPDATE members SET page = :page WHERE memberid = :memberid');
        $stmt->execute(array(':memberid' => $_SESSION['memberID'], ':page' => $_POST['button2']));
        $array = $stmt -> fetchAll(PDO::FETCH_ASSOC);
        $_SESSION["page"] = $_POST['button2'];
        header ('Location: memberpage.php?page=' . $_SESSION["page"]);
}

The array keys are simple - they're just strings:

for($i = 1; $i <= 2; $i++) {
    if (isset($_POST["button$i"]) etc....
                            ^^

For the variables, you should probably consider storing those in an array instead of using numbered vars:

  if (isset($_POST["button$i"]) == $buttons[$i]))

You COULD use var-vars, but that just makes the code a maintenance nightmare later on:

$temp = "button" . $i;
if (.... == $$temp)
            ^^    

Use variable variables in a for loop - this will allow as many if conditions as you want assuming the pattern holds.

for($i = 1; $i <= $numberOfConditions; $i++) {

    $postKey = "button" . $i;

    if (isset($_POST[$postKey]) && ($_POST[$postKey] === $$postKey )) {

        $stmt = $db->prepare('UPDATE members SET page = :page WHERE memberid = :memberid');
        $stmt->execute(array(':memberid' => $_SESSION['memberID'], ':page' => $_POST[$postKey]));
        $array = $stmt -> fetchAll(PDO::FETCH_ASSOC);
        $_SESSION["page"] = $_POST[$postKey];
        header ('Location: memberpage.php?page=' . $_SESSION["page"]);

    }
}

}

It seems to me like you could name the input on the HTML side just "button" and get away with doing a single if check...

//append the button values to an array
$page_array = array(232, 363);

//add the code to a function for future use
changePage($page_array);


    function changePage($page_array){
    if(($_SERVER["REQUEST_METHOD"] == "POST") && isset($_POST['button']) && in_array($_POST['button'], $page_array)){
         $stmt = $db->prepare('UPDATE members SET page = :page WHERE memberid = :memberid');
         $stmt->execute(array(':memberid' => $_SESSION['memberID'], ':page' => $_POST['button']));
         $array = $stmt -> fetchAll(PDO::FETCH_ASSOC);
         $_SESSION["page"] = $_POST['button'];
         header ('Location: memberpage.php?page=' . $_POST['button']);
    } else {
       echo "ERROR";
    }
}

Again, I'm sort of guessing as to what your code is actually doing, but it seems like you're defining each button and setting a page to it.. ? On your html side you can just do like..

<!--- the button values are added from the initial array -->
<form method="post">
<button type="submit" name="button" value="<?php echo $page_array[0]; ?>">Option 1</button>
<button type="submit" name="button" value="<?php echo $page_array[1]; ?>">Option 2</button>
</form>

the $page_array will define a list of accepted pages (if that's what you're looking for..) and in_array just checks to make sure the value passed from post exists in the list of accepted pages.

-- Accepted your edits, adding this:

If your view has access to your page array, and you want to use it in your buttons for easy maintenance, you could go one step further, like this..

$page_array = array(
    232 => 'Page Name',
    363 => 'Page Name'
);

Change your function if check from this:

if(($_SERVER["REQUEST_METHOD"] == "POST") && isset($_POST['button']) && in_array($_POST['button'], $page_array)){

To this:

if(($_SERVER["REQUEST_METHOD"] == "POST") && isset($_POST['button']) && array_key_exists($_POST['button'], $page_array)){

Now in your HTML you can do this:

<form method="post">
    <?php foreach($page_array as $page_number => $page_name): ?>
        <button type="submit" name="button" value="<?php echo $page_number; ?>"><?php echo $page_name; ?></button>
    <?php endforeach; ?>
</form>

You can convert your code into an anonymous function:

$updatePage = function($page) use ($db) {
    $stmt = $db->prepare('UPDATE members SET page = :page WHERE memberid = :memberid');
    $stmt->execute(array(':memberid' => $_SESSION['memberID'], ':page' => $page));
    $array = $stmt -> fetchAll(PDO::FETCH_ASSOC);
    $_SESSION["page"] = $page;
    header ('Location: memberpage.php?page=' . $_SESSION["page"]);
}

Then where you want to use it simply call the function:

if (isset($_POST['button1']) && ($_POST['button1']) == $button1 ){
    $updatePage(1);
}
elseif (isset($_POST['button2']) && ($_POST['button2']) == $button2 ){
    $updatePage(2);
}

Or add it into a loop:

$buttons = array('button1', 'button2');
foreach ($buttons as $button) {
    if (isset($_POST[$button])) {
         $updatePage($_POST[$button]);
    }
}

The purpose of functions in code is to reduce repetitive code... we could make this far better by using a class and assigning the db object to it and then calling the method. You can then do much more with your class by asking it to perform the tests, so if you test changes you only change it in one place. It really depends on the rest of your code and we're all making assumptions based on the little snippet you added. This would basically be your Controller.

Rule of thumb, if you're writing the same bit of code twice, make it a function. You never know if you need to change the business logic around it ( foreach vs if vs switch ), but at least the action will remain the same and you won't need to refactor as much.

My suggestion would be the following:

 // This is the same in both so doesn't need put in both
$stmt = $db->prepare('UPDATE members SET page = :page WHERE memberid = :memberid');

// The if only really checks what value you should use, so...
if (isset($_POST['button1']) && ($_POST['button1']) == $button1 ){
    $uButton = $button1;
} else { // Put the else if back in if you like, but if you do, add an else
    $uButton = $button2;
}

// Aside from the variable above, all these lines were identical too
$stmt->execute(array(':memberid' => $_SESSION['memberID'], ':page' => $uButton));
$array = $stmt -> fetchAll(PDO::FETCH_ASSOC);
$_SESSION["page"] = $uButton;
header ('Location: memberpage.php?page=' . $_SESSION["page"]);

This is dependent on other code. Ie the entire block may need to go in another condition checking whether at least one of the 2 buttons is available.

Unlike Marc's answer, this one does not consider that you have any more than 2 button inputs but it can be adapted with his answer's suggestions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM