PHP form - processing multiple checkboxes

Hello forum,

I have been trying to create php mail form that has input fields, radio buttons and check boxes. Currently stuck with collecting info from check boxes… I tried multiple ways but either getting only one checkbox title or ‘Array’

At the moment this is my php file code:

<?php 
if(isset($_POST['submit'])){
	$q1 = $_POST['Q1'];
	$q2 = $_POST['Q2'];
	$q3 = $_POST['Q3'];
	$q4 = $_POST['Q4'];
	$q5 = $_POST['Q5'];
if(!empty($_POST['Q6'])){
foreach($_POST['Q6'] as $q6){
echo $q6."</br>";
}
}
	$q7 = $_POST['Q7'];
	$q8 = $_POST['Q8'];
	$q9 = $_POST['Q9'];
	$q10 = $_POST['Q10'];
	$q11 = $_POST['Q11'];
	$q12 = $_POST['Q12'];
	$q13 = $_POST['Q13'];
	$q14 = $_POST['Q14'];
	$q15 = $_POST['Q15'];
	$q16 = $_POST['Q16'];
	$q17 = $_POST['Q17'];
	$q18 = $_POST['Q18'];
	$q19 = $_POST['Q19'];
	$q20 = $_POST['Q20'];
	$q21 = $_POST['Q21'];
	$q22 = $_POST['Q22'];
    $to = "info@xxxxxxx.com";
    $from = $_POST['Q20'];
    $first_name = $_POST['Q17'];
    $last_name = $_POST['Q18'];
    $subject = "New client";
    $message = "Anzahl Patienten: " . $q1 . "\n\n" . "Patient 1 Geschlecht : " . $q2 . "\n\n" . "Patient 2 Geschlecht (wenn anwendbar): " . $q3 . "\n\n" . "Mobilität von Patient 1: " . $q4 . "\n\n" . "Mobilität von Patient 2 (wenn anwendbar): " . $q5 . "\n\n" . "Erforderliche Dienstleistungen: " . $q6 . "\n\n" . "Erforderliche Dienstleistungen bei: " . $q7 . "\n\n" . "Krankheiten: " . $q8 . "\n\n" . "Andere Krankheiten: " . $q9 . "\n\n" . "Weitere Informationen: " . $q10 . "\n\n" . "Pflegedauer: " . $q11 . "\n\n" . "Startdatum: " . $q12 . "\n\n" . "Endtermin: " . $q13 . "\n\n" . "Spezielles Zimmer für die Pflegekraft: " . $q14 . "\n\n" . "Eigenes Badezimmer für die Pflegekraft: " . $q15 . "\n\n" . "WLAN-Netzwerk im Haus: " . $q16 . "\n\n" . "Ihr Name: " . $q17 . "\n\n" . "Ihr Familienname: " . $q18 . "\n\n" . "Ihr Telefonnummer: " . $q19 . "\n\n" . "Ihr E-Mail-Adresse: " . $q20 . "\n\n" . "Ihr Stadt: " . $q21 . "\n\n" . "Ihr Postleitzahl: " . $q22 . "\n\n";
    
    $headers = "From:" . $from;
    mail($to,$subject,$message,$headers);
    header("Location: https://www.xxxxxxx.com/index.html");
    }
?>

And part of my HTML:

<form id="customer_form" action="mail_handler.php" method="post" class="form-horizontal" style="background-color: rgba(255,255,255,0.1)" autocomplete="off" onsubmit="alert('Danke für die Information. Ich werde bald antworten.');";>

<div class="form-group" style="background-color: rgba(250, 250, 250, 0.15);">
  <label class="col-md-4 control-label" for="Q6">Erforderliche Dienstleistungen </label>
  <div class="col-md-4">
  <div class="checkbox">
    <label for="Q6-0">
      <input type="checkbox" name="Q6[]" value="Mahlzeiten zubereiten, Geschirr spülen und Geschirrspüler be-/entladen">
      Mahlzeiten zubereiten, Geschirr spülen und Geschirrspüler be-/entladen
    </label>
	</div>
  <div class="checkbox">
    <label for="Q6-1">
      <input type="checkbox" name="Q6[]" value="Esshilfe">
      Esshilfe
    </label>
	</div>
  <div class="checkbox">
    <label for="Q6-2">
      <input type="checkbox" name="Q6[]" value="Spezielles Essen erforderlich">
      Spezielles Essen erforderlich
    </label>
	</div>
  <div class="checkbox">
    <label for="Q6-3">
      <input type="checkbox" name="Q6[]" value="Wäsche, Bügeln &amp; Bettzeug">
      Wäsche, Bügeln &amp; Bettzeug
    </label>
	</div>
  <div class="checkbox">
    <label for="Q6-4">
      <input type="checkbox" name="Q6[]" value="Allein einkaufen">
      Allein einkaufen
    </label>
	</div>
  <div class="checkbox">
    <label for="Q6-5">
      <input type="checkbox" name="Q6[]" value="Gemeinsam einkaufen">
      Gemeinsam einkaufen
    </label>
	</div>
  <div class="checkbox">
    <label for="Q6-6">
      <input type="checkbox" name="Q6[]" value="Erledigung der Hausarbeit">
      Erledigung der Hausarbeit
    </label>
	</div>

First thing, stop creating a bunch of variables for nothing. Secondly, this code is vulnerable to an email header injection attack. The From should be from the server this resides on, not from random spammer using this. I also do not see a proper form here.

Never Ever Trust User Supplied Data.

Hi benanamen and thanks for your post.

I am only beginner and learning through the php, so not sure what you are referring to as “bunch of variables” (can only assume it related to php check boxes code?)

I also don’t know how this code would be vulnerable without further explanation.

Everywhere you are assigning a new variable to the POST variables. Nothing has changed. No reason to create new variables.

Look up Email Header Injection Attack for info on the other part.

Does it mean I can just use direct value such as $_POST[‘Q1’]?

I have read quick article about the injection attack - it was on my list to implement some sort of character validation, but right now, it does not do what I want to start with…

Yes.

If you were to dump the checkbox form data you would see you are getting an array like so…

array (size=1)
‘Q6’ =>
array (size=4)
0 => string ‘Spezielles Essen erforderlich’ (length=29)
1 => string ‘Allein einkaufen’ (length=16)
2 => string ‘Mahlzeiten zubereiten, Geschirr spülen und Geschirrspüler be-/entladen’ (length=72)
3 => string ‘Allein einkaufen’ (length=16)

You need to modify your foreach like so to get the values of that array…

foreach($_POST['Q6'] as $key => $value){
echo $value."</br>";
}

Thanks, but I am still having only one check box value?

Start with this

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($_POST['Q6'])) {
        foreach ($_POST['Q6'] as $key => $value) {
            echo $value . "</br>";
        }
    }
}
?>
<form method="post">

<div class="form-group" style="background-color: rgba(250, 250, 250, 0.15);">
  <label class="col-md-4 control-label" for="Q6">Erforderliche Dienstleistungen </label>
  <div class="col-md-4">
  <div class="checkbox">
    <label for="Q6-0">
      <input type="checkbox" name="Q6[]" value="Mahlzeiten zubereiten, Geschirr spülen und Geschirrspüler be-/entladen">
      Mahlzeiten zubereiten, Geschirr spülen und Geschirrspüler be-/entladen
    </label>
    </div>
  <div class="checkbox">
    <label for="Q6-1">
      <input type="checkbox" name="Q6[]" value="Esshilfe">
      Esshilfe
    </label>
    </div>
  <div class="checkbox">
    <label for="Q6-2">
      <input type="checkbox" name="Q6[]" value="Spezielles Essen erforderlich">
      Spezielles Essen erforderlich
    </label>
    </div>
  <div class="checkbox">
    <label for="Q6-3">
      <input type="checkbox" name="Q6[]" value="Wäsche, Bügeln &amp; Bettzeug">
      Wäsche, Bügeln &amp; Bettzeug
    </label>
    </div>
  <div class="checkbox">
    <label for="Q6-4">
      <input type="checkbox" name="Q6[]" value="Allein einkaufen">
      Allein einkaufen
    </label>
    </div>
  <div class="checkbox">
    <label for="Q6-5">
      <input type="checkbox" name="Q6[]" value="Gemeinsam einkaufen">
      Gemeinsam einkaufen
    </label>
    </div>
  <div class="checkbox">
    <label for="Q6-6">
      <input type="checkbox" name="Q6[]" value="Erledigung der Hausarbeit">
      Erledigung der Hausarbeit
    </label>
    </div>
  <input type="submit" value="Submit">
  </form>

As you are already using the variable $q6 in your email message you should define it so there are no errors when q6 checkboxes are not checked. You can then loop through them as Benanamen described and concatenate them together with the line breaks you wish to have. Something like this.

$q6 = '';
if(!empty($_POST['Q6'])){
	foreach($_POST['Q6'] as $k => $q6v){
		if(!empty($q6v)){
			$q6 .= "\n\n".$q6v;
		}
	}
}

Thanks, this seems to work fine. I have modified the output lines as I prefer to have in line rather than list.

Since I have two questions with checkboxes, I wrote second code based on first one, but I am not getting any results (for q8). I made assumption that $k was local variable and for second question changed to $g - is this correct?

<?php 
if(isset($_POST['submit'])){
	$q1 = $_POST['Q1'];
	$q2 = $_POST['Q2'];
	$q3 = $_POST['Q3'];
	$q4 = $_POST['Q4'];
	$q5 = $_POST['Q5'];
	$q6 = '';
	if(!empty($_POST['Q6'])){
		foreach($_POST['Q6'] as $k => $q6v){
			if(!empty($q6v)){
				$q6 .= $q6v . ", ";
			}
		}
	}
	$q7 = $_POST['Q7'];
	$q8 = '';
	if(!empty($_POST['Q8'])){
		foreach($_POST['Q8'] as $g => $q8v){
			if(!empty($q8v)){
				$q8 .= $q8v . ", ";
			}
		}
	}
	$q9 = $_POST['Q9'];
	$q10 = $_POST['Q10'];
	$q11 = $_POST['Q11'];

Thanks, I will try it out, though my php statements start slightly different (might be using older method…)

I figured out what was wrong - the brackets [ ] were missing withint the name=“x” field.

Also found out my assumption on changing $k was wrong. Is the $k short version of $key?

In this case, it does happen contain the array key / index of each element of $_POST['Q6'], within the scope of the foreach() loop. In that sense it’s a local variable, try to use it outside the foreach() and you won’t be able to. But the name could be anything, and because you have two separate foreach() loops, it wouldn’t matter if you used the same variable names for the loop in both of them. If they were nested within each other, using the same names would cause a problem.

2 Likes

That’s not exactly true. While the array would not be available outside the loop as coded, the last element of the key and the value would be. You could unset them but I have never seen a need to do that.

2 Likes

I have vague memories that the outside of the loop $key value could change depending on the PHP version.