Inserting multiple checkboxes in mysql

I am having a bit of difficulty inserting the values in my database. would you be able to see why?

here is my form:

 <form action="" method="post" id="attendanceForm">
              
              <div class="stretch">
				<?php 
                $attendee = DB::getInstance()->query("SELECT id, firstname, lastname FROM associates");
                      if($attendee->count()){
                        foreach($attendee->results() as $row){
                            echo '<label class="labelCheckBox"><input type="checkbox"  name="attendee[]" id="attendee[]" value="'. $row->id .'">'. '   ' 
                                     .$row->firstname .' ' . $row->lastname .'</label> <br />';
                        }
                      }
                  ?>
              </div>
              <input type="hidden" name="fireSafetyID" value="$_get[fireSafetyID]">
              <input type="hidden" name="token" value="<?php echo Token::generate(); ?>">
              <div class="submit">
                <input type="submit" class="button" name="attendance" id="attendance" value="Save">
              </div>
                
          </form>

Here is my script:

require_once 'core/init.php';
$user = new User();
$current='fireSafetyAttendance';
$pageTitle= 'Fire Safety Drill Attendance';
error_reporting(E_ALL | E_STRICT);
//if(!$user->isLoggedIn() || $user->data()->group <2){
		//Redirect::to('index.php');
		//Session::flash('home', '<<<----Sorry, you are not authorized to access the Fire Safety Report page----->>>.');
	//}
	if(Input::exists()) {
	          try { 
			if(isset($_POST['attendee'])){
				$attendee = implode(',',$_POST['attendee']);
			}
			else
			{
				$attendee='';	
			}	
		echo $attendee;//-This works ok
		$fsa=DB::getInstance()->insert('fsattendances', array(
						'attendee' => $attendee
					));
					Session::flash('home', '<<<----The Attendance for your Drill has been saved.  Please complete the Fire Safety Report by listing Training components----->>>.');
					
					//Redirect::to('firesafetycomponent.php');
				} catch(Exception $e) {
					echo 'Exception -> ';
					die($e->getMessage());
				}
			
	}

this is my insert class:

public function insert($table, $fields = array()) {
            $keys = array_keys($fields);
            $values = '';
            $x = 1;
            foreach($fields as $field) {
                $values .= '?';
                if($x < count($fields)) {
                    $values .= ', ';
                }
                $x++;
            }
            $sql = "INSERT INTO {$table} (`" . implode('`, `', $keys) . "`) VALUES ({$values})";
            if(!$this->query($sql, $fields)->error()) {
                return true;
            }
            return false;
        }

is invalid HTML.

means that your database is not normalized - you should never store comma separated lists in a single field - each should have their own row in a separate table.

yes that was my first idea: one row per value. I was trying to attack this problem in steps that I can handle: first-> get to see if I can actually get values out of my form to the database: That was done ok. The second step was to get the values into the column. that was done also. Now I am at trying to not implode the values and insert the values in a separate row for each. Next I have o attack how I can transfer the id number of the last form that was submited so I can reference it into this form that I am building. I’m just not too familiar with php yet. but learning everyday. I found that if I break the task in little piece that I can handle one at the time, I sometime get lucky and able to do what I want to do without too much problem. This is where I am at the moment → getting these values into a separate row and then figure out how to pass the ID of the last transaction on hte previous page so I can reference it in this current form.

I removed the id=‘attendee’ as you suggested and I was able to upload my values into my table correctly. NOW!, follow up question? I would rather return my column type to integer and insert a single value per row as you suggest. would you know how to proceed in doing that? with a while loop?

Your current insert function is not designed to handle multiple-row inserts, and changing it could cause issues with other inserts. That said, if i was going to tweak your function, it would be to make $fields a multdimensional array, and foreach the whole shebang.

public function insert($table, $values = array()) {
//Foreach $values as $fields:
            $keys = array_keys($fields);
             //Lets clean this next loop up a bit with an array function...
            $values = implode(",",array_fill(1,count($fields),"?"));
            $sql = "INSERT INTO {$table} (`" . implode('`, `', $keys) . "`) VALUES ({$values})";
            if(!$this->query($sql, $fields)->error()) {
                return true;
            }
// EndForeach
            return false;
        }

Alternatively, Foreach the insert call.

 foreach($_POST['attendee'] AS $attendee) { //PS: Dont do this. Validate your input before walking it. Even with prepared statements.
	$fsa=DB::getInstance()->insert('fsattendances', array(
					'attendee' => $attendee
				));
 }

thank you StarLion.

I am obviously missing something on my input part of the revised function you wrote for me:

Notice: Undefined variable: fields in C:\xampp\htdocs\database\classes\DB.php on line 105

Warning: array_keys() expects parameter 1 to be array, null given in C:\xampp\htdocs\database\classes\DB.php on line 105

Notice: Undefined variable: fields in C:\xampp\htdocs\database\classes\DB.php on line 107

Warning: implode(): Invalid arguments passed in C:\xampp\htdocs\database\classes\DB.php on line 108

Notice: Undefined variable: fields in C:\xampp\htdocs\database\classes\DB.php on line 109

I don’t mind having to modify the function on the page like on the second example if it makes thing simpler for me.

Question: Why would I want to validate checkboxes? aren’t checkboxes boolean?

Not if someone chanes the output from your form and makes the checkboxes into something else.

You say they’re boolean, i say they’re post fields, and post fields have no type.

You’re a PHP script. You see the following:

$var = $_POST[‘imaformfield’];

What type is $var?

Also, if you changed the function in the way that i said, you must change all instances of insert calls to pass a multidimensional array.

That’s called a security hole.

$_POST['imaformfield'] can contain anything and with that assignment now $var can contain anything too. While $_POST and other fields starting $_ can contain anything and are therefore tainted you should always validate or sanitize before moving the value to another field so as to not taint all of the fields in your script.

1 Like

what I done is I used the alternative you gave me as a second option. that worked wonderfully, thank you. I kept the method you wrote and saved it as insertArray, so I can use it when I need it. All this is very new to me especially pdo which I just started a couple of weeks ago. so in time I will make sense of all the ehlp I get from this wonderful forum and start seeing how I can utilize everything that is shown to me. Right now, it’s baby steps trying to make things work first and then get things tighter and better.

so what I did for validation I used trim, escape and tested for is_numeric. since it will always be nothing but id number and only have one field I think I should be ok, right?

Oh okay. That makes sense.

If it were me, i’d cast the values to int, since that’s what (i assume) your attendee ID’s are, and then just double-check that the value is not 0.

good idea, I will add that to the validation, thanks. While I have you, can I impose another question? I need one more field populated in a hidden input field. I want to pass the firesafetyID of the previous form that was inserted in the database prior to be redirected to this attendance form where I will check whomever participated in the fire drill(which is kept into a separate table but want to bring a foreign key inside this attendance for that I am inserting? I know I can either do it by the url with a $_get or maybe through $session. which would be the best to use? I;m learning both not sure which would be best at this time.

So… presumably the processing of the previous form directs the user to the current form. How are you accomplishing that? Include? Header-Redirect?

that is correct.

this following script process a fire safety report and then save it to the database. I once used a function called something like used_last_ID or something of the like and was able to recall the id number mysql gave to ID column at the last insert. I figured I could used that function and pass it along with the redirect() function at the bottom of the script?

<?php require_once 'core/init.php';
$user = new User();
$current='fireSafetyReport';
$pageTitle= 'Fire Safety Drill Report';

//if(!$user->isLoggedIn() || $user->data()->group <2){
        //Redirect::to('index.php');
        //Session::flash('home', '<<<----Sorry, you are not authorized to access the Fire Safety Report page----->>>.');
    //}
    if(Input::exists()) {
        
        
        if(Token::check(Input::get('token'))) {
            
            $validate = new Validate();
            $validation = $validate->check($_POST, array(
                'FSSiteid' =>array(
                    'required' => true,
                ),
                'FSDate' =>array(
                    'required' => true,
                ),
                'action' =>array(
                    'required' => true,
                ),
                'prepByAssociateid' =>array(
                    'required' => true,
                ),
                'reviewedByAssociateid' =>array(
                    'required' => true,
                )
                
            ));
            
            if($validation->passed()) {
                
                try {                         
                $fs=DB::getInstance()->insert('firesafety', array(//////I took the $user-> before DB::getINstance
                        'FSSiteid' => Input::get('FSSiteid'),
                        'FSDate' => Input::get('FSDate'),
                        'FSTimeStart' => Input::get('FSTimeStart'),
                        'FSTimeStop' => Input::get('FSTimeStop'),
                        'action' => Input::get('action'),
                        'deviceid' => Input::get('deviceid'),
                        'locationid' => Input::get('locationid'),
                        'staffPosted' => Input::get('staffPosted'),
                        'elevatorLock' => Input::get('elevatorLock'),
                        'DWClosed' => Input::get('DWClosed'),
                        'corridorClear' => Input::get('corridorClear'),
                        'powerOff' => Input::get('powerOff'),
                        'bellLights' => Input::get('bellLights'),
                        'procedureFollowed' => Input::get('procedureFollowed'),
                        'residentPanic' => Input::get('residentPanic'),
                        'prepByAssociateid' => Input::get('prepByAssociateid'),
                        'reviewedByAssociateid' => Input::get('reviewedByAssociateid'),
                        'drillDescription' => Input::get('drillDescription'),
                        'followUp' => Input::get('followUp'),
                        'FSComment' => Input::get('FSComment'),
                    ));
                    Session::flash('home', '<<<----Your Fire Safety Report has been saved. Please continue by taking an attendance to the Drill----->>>.');
                    
                    Redirect::to('firesafetyattendance.php');
                } catch(Exception $e) {
                    die($e->getMessage());
                }
            } else {
                foreach ($validation->errors() as $error) {
                    echo $error, '</br>';
                }
            }
        }
        
    }

?>

So does your database interaction class specify a means of retrieving said ID? The insert function is programmed to return an inverse boolean, rather than the id…

I;m not exactly sure to be honest? As mentioned previously I am learning as I go. The classes for my site are classes built part of a tutorial that I followed online. I am starting to figure out how I can work with the class and how I can and cannot use them or create my own. I managed to get what I wanted to accomplish(probably not very elegantly) but it nevertheless works with the following:

$_SESSION['lastId'] = DB::getInstance()->lastId();

I then went into DB classes and created the following class (out of shire luck I might add lol)

public function lastId(){
			return $this->_pdo->lastInsertId();
		}

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.