0

I'm trying to figure out a way to remove checkbox values from a SESSION.

I have a form with a checkbox array, among other fields. When the form is submitted, the field values are stored in a SESSION, so that if the user refreshes the page, the values stick.

However, if they then uncheck the checkboxes and re-submit the form, the checkbox values still stick because the checkbox name never gets posted in the POST array, so I don't know which values to unset()

I'm trying to come up with a way to look into the SESSION and remove anything that's not in POST.

This is what I have so far, but it's just not working right because it's checking for a non-existent value in POST. I think it's backwards, but I haven't been able to figure out how to reverse it.

foreach ($_POST as $post_key => $post_value) {
    if (is_array($post_value)) {
        $result = array_diff($_SESSION[$this->session], $_POST[$post_key]);
        foreach ($result as $key => $value) {
            if (($k = array_search($value, $_SESSION[$this->session])) !== false) {
                unset($_SESSION[$this->session][$k]);
            }
        }
    }
}

The POST checkbox array is basically

Array
(
    [food] => Array
        (
            [0] => steak
            [1] => chicken
        )

    [submit] => Submit
)

Of course, when no checkboxes are checked, it looks like this, so I don't know what to unset()

Array
(
    [submit] => Submit
)

timgavin
  • 4,972
  • 4
  • 36
  • 48
  • 1
    Here is one approach: [POST unchecked HTML checkboxes](https://stackoverflow.com/questions/1809494/post-unchecked-html-checkboxes). Many [variations](https://stackoverflow.com/questions/2520952/how-come-checkbox-state-is-not-always-passed-along-to-php-script) of that asked here. – ficuscr Sep 30 '20 at 21:23
  • @ficuscr Thanks, this led me to the answer :) – timgavin Oct 03 '20 at 20:44

1 Answers1

0

Here's what I did. I created a hidden element that contains all of the checkbox array values and put that into the form.

<input type="hidden" name="food_values" value="steak,chicken,fish">

Upon POST, I explode that hidden element into an array: $hidden_checkbox_values.

I then take each $_POST['food'] checkbox value and put it into the SESSION.

I then array_diff() the $hidden_checkbox_values array against the $_POST['food'] array. If a value is in $hidden_checkbox_values but not in $_POST['food'], I remove it from the SESSION as it wasn't ticked when the form was submitted.

If there are no values in the POST array, then all checkboxes were unchecked, and I remove all checkbox values from the SESSION.

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // get all checkbox values from the hidden element and put them into an array
    $hidden_checkbox_values = explode(',', $_POST['food_values']);

    if (isset($_POST['food'])) {
        if (isset($_SESSION['myForm']))
        {
            // add all POSTed checkbox values to the session
            foreach ($_POST['food'] as $key => $value) {
                if (!in_array($value, $_SESSION['myForm'])) {
                    $_SESSION['myForm'][] = $value;
                }
            }

            // if a value from our values array is NOT in our POST array, remove it from the session
            $clean1 = array_diff($_POST['food'], $hidden_checkbox_values);
            $clean2 = array_diff($hidden_checkbox_values, $_POST['food']);
            $output = array_merge($clean1, $clean2);
            foreach ($output as $value) {
                foreach ($_SESSION['myForm'] as $skey => $svalue) {
                    if ($svalue == $value) {
                        unset($_SESSION['myForm'][$skey]);
                    }
                }
            }
        }
    } else {
        // all checkboxes were unchecked, remove all checkbox values from the session
        foreach ($hidden_checkbox_values as $value) {
            foreach ($_SESSION['myForm'] as $skey => $svalue) {
                if ($svalue == $value) {
                    unset($_SESSION['myForm'][$skey]);
                }
            }
        }
    }
}
timgavin
  • 4,972
  • 4
  • 36
  • 48