Pass multiple variable through single checkbox - php

I am not sure the best way to do this or if it's even possible. Basically I have a checkbox that looks like this:
php
foreach($clients as $client){
echo'
<input type="checkbox" name="client_data[]" value="'.$class_id.'">
'.$client['first_name'].' ('.$client['nickname'].') '.$client['last_name'].'
<br />';
} // foreach($client
HTML looks like this
<form method="post" action="">
<input type="checkbox" value="?" name="client_data[]">
Dwayne (The Rock) Johnson<br>
<input type="checkbox" value="?" name="client_data[]">
Steve (Puddin) Robinson<br>
<input type="submit" value="Add" name="exist_to_class">
</form>
When the form is submitted I want to insert the
$first_name, $nickname, $lastname
into the db with a query that looks like this:
mysql_query("INSERT INTO `clients` (`user_id`, `first_name`, `last_name`, `nickname` `class_id`)
VALUES ('$user_id', '$first_name, '$last_name', '$nickname', '$class_id')");
Is this possible or am I even close on how I am attempting to set this up? I have not had much luck so far.
My db table looks like this:
I need to be able to enter the client multiple time with different class_id's.
What is the best way to accomplish this?
Here is the code that call the function to insert data into db:
if (isset($_POST['exist_to_class'])){
if (empty($_POST['client_data']) === true){
$errors [] = 'You much select a client to be added to the class.';
} else {
if (isset($_POST['client_data']) && !empty($_POST['client_data']));
list($first_name, $nickname, $last_name) = explode('|', $_POST['client_data']);
exist_client_to_class($class_id);
header('Location: view_class.php?class_id='.$class_id.' ');
}
} //isset
And here is my query:
function exist_client_to_class($class_id, $user_id){
$class_id = (int)$class_id;
$user_id = (int)$user_id;
mysql_query("INSERT INTO `clients` (`user_id`, `first_name`, `last_name`, `nickname` `class_id`)
VALUES ('$user_id', '$first_name, '$last_name', '$nickname', '$class_id')");
}
What am I doing wrong?

You can't pass more than one variable through a single checkbox. Marc B is right, in that if this is a database-backed application then the right way to do it would be to have the checkbox send the ID for the person who's selected, and use the ID to look up whatever information you need about them.
If you're not using a database, a quick-and-dirty way to do this would be to put the information about the person into an array and then run it through serialize() to turn it into a string and use that as the value attribute. On the other end you can run it through unseialize() to get back the array with the values you wanted.
Remember that if you do this, you need to either escape your sql query or (very strongly preferred) use a prepared query.

okay, you may path string in value as Asad suggested and than split it on the server, like this
foreach($clients as $client){
echo'
<input type="checkbox" name="client_data" value="'.$class_id.'|'.$client['first_name'].'|'.$client['nickname'].'|'.$client['last_name'].'">
'.$client['first_name'].' ('.$client['nickname'].') '.$client['last_name'].'
<br />';
} // foreach($client
and on the server have something like
list($class_id, $first_name, $nickname, $last_name) = explode('|', $_POST['client_data'])
mysql_query("INSERT INTO `clients` (`user_id`, `first_name`, `last_name`, `nickname` `class_id`)
VALUES ('$user_id', '$first_name, '$last_name', '$nickname', '$class_id')");
I am not sure where from $class_id variable in template and $user_id in the model, so you have to figure it out, also drawback here is that if in some variable will be placed delimiter | data will be split wrong. To avoid it you may use hidden inputs associated somehow with the main checkbox (javascript, logic or whaterver will play best in your case)
UPD: oh yea you may serialize/unserialize data as array http://us3.php.net/serialize as octern suggestion

Related

Concatenation of multiple user entries and submission into a single MySQL database entry

I am referencing to a question here: Can I concatenate multiple MySQL rows into one field?
In this question multiple rows of a column are listed and separated by a "," using the GROUP_CONCAT function. I want to achieve something in reverse by concatenating multiple user inputs into a single database entry. Something like this:
<form action="server.php" method="POST">
<div>
<input type="text" name="value1">
<input type="text" name="value2">
<input type="text" name="value3">
<button type="submit" name="submit">submit</button>
</div>
</form>
and php:
<?php
if (isset($_POST['submit'])) {
$value1 = mysqli_real_escape_string($conn, $_POST['value1']);
$value2 = mysqli_real_escape_string($conn, $_POST['value2']);
$value3 = mysqli_real_escape_string($conn, $_POST['value3']);
$sql = "INSERT INTO database (col1)
VALUES GROUP_CONCAT('$value1', '$value2', '$value3');";
mysqli_query($conn, $sql);
header("Location: ../web_page/client_database_page.php?add_client=success");
}
?>
I know some of you will say that it would not be good practice to do this and I should have an individual column for each user input, however there is a reason for not doing it this way. The user inputs are added based on the number of variables from another database. In this database a user can insert additional user inputs from the website, but it would not automatically add a column to the input database. So a single column row should be able to contain all the user inputs and than later be separated for interpretation when called from the database.
Anybody have any ideas?
How about grouping your input values as an array then using implode() function in PHP before you insert into DB, like:
<form action="server.php" method="POST">
<div>
<input type="text" name="values[]">
<input type="text" name="values[]">
<input type="text" name="values[]">
<button type="submit" name="submit">submit</button>
</div>
</form>
Then, in PHP:
if (isset($_POST['submit'])) {
$values = $_POST['values'];
$escaped_values = array_map([$conn, 'mysqli_real_escape_string'], $values);
$concat_values = implode(",", $escaped_values);
$sql = "INSERT INTO database (col1) VALUES ('$concat_values');";
mysqli_query($conn, $sql);
header("Location: ../web_page/client_database_page.php?add_client=success");
}
Here, I used comma , as separator on each values. Just change it to your preference.
EDIT:
Another solution would be to use JSON for this so you can easily access the data when retrieved. Depending on your MySQL version, you can use the JSON data type for the col1 column/field.
ALTER TABLE `table_name` CHANGE COLUMN `col1` `col1` JSON;
Then modify the code to:
$json = json_encode($_POST['values']);
$sql = "INSERT INTO database (col1) VALUES ('$json');";
And then later when you retrieve the data you can do something like:
$values = json_decode($row['col1'], true);
Which you can then iterate to echo multiple <input> tags with values taken from the db.
You can simply concat values using PHP. No need to use GROUP_CONCAT for this.
Try code like below:
$sql = "INSERT INTO database (col1) VALUES ('$value1 $value2 $value3');";
Note: Values can be separated by comma , or any other separator instead of space.

Save datas from multiple checkbox in a database

2 Questions about saving data from multiple checkbox (I have few of them in my form) in a database with PDO (PHP). I just show the relevant parts of the code to make it more simple for everyone.
A) The code I wrote works (still saving all data correctly) but it gives me still a failure message, which you can see below. Why, or what can I do better?
B) It saves the checked checkboxes as an array in the database. Later on I want to change data by getting the data from the database back into my original form - will it make problems, if its saved like an array? If yes, what would you recommend to do then better.
Warning: implode ( ) : Invalid arguments passed on line ... for
$p2 = implode(',',$product_2);
$p3 = implode(',',$product_3);
$p1 = implode(',',$product_1); which I defined first seems to be fine
<?php
if(isset($_POST['send']))
{
require("php/tconnect.php");
$id = $_POST['id'];
$name = $_POST['name'];
$date = $_POST['date'];
$p1 = implode(',',$product_1);
$p2 = implode(',',$product_2);
$p3 = implode(',',$product_3);
$sql = "INSERT INTO database (id, name, date) VALUES (:id, :name, :date, '$p1', '$p2', '$p3')";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->bindValue(':date', $date);
$stmt->execute();
echo "Datas saved";
}
?>
HTML
<input type="checkbox" name="product_1[]" value="apple" id="product_1_apple">
Apple
</label>
<label class="checkbox-inline">
<input type="checkbox" name="product_1[]" value="Banana" id="product_1_banana">
Banana
</label>
and the next tables looks similar
<input type="checkbox" name="product_2[]" value="water" id="product_2_water">
Water
</label>
<label class="checkbox-inline" >
<input type="checkbox" name="product_2[]" value="juice" id="product_2_juice">
Juice
</label>
Since $product_1, $product_2 and $product_3 seems to be related with the input arrays from the HTML I suppose that you have in another part of the code something like this:
$product_1 = $_POST['product_1'];
$product_2 = $_POST['product_2'];
$product_3 = $_POST['product_3'];
Now, the problem is that those variables are related to an array of checkboxes, but when no checkbox is selected in the page for a group, instead of getting an empty array for that group the array is not added to $_POST (you can see it using var_dump($_POST)).
I suspect that in your tests you were only marking checkboxes for product_1, so you get an array for that product but no for the other ones. To prevent the error you can fill each of the products variables using something like this:
if(isset($_POST['product_1'])) // if the array is defined in $_POST
$product_1 = $_POST['product_1']; // fill with the array from the form
else $product_1 = array(); // fill with empty array, you get the empty string with implode()
// repeat for product_2 and product_3
Also, you are mixing prepared statements, which are good, with inserting the values directly in the query string, which is bad because it can lead to SQL Injection, you should use bindValue() for all the values of the table:
$sql = "INSERT INTO database (id, name, date) VALUES (:id, :name, :date, :p1, :p2, :p3)";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->bindValue(':date', $date);
$stmt->bindValue(':p1', $p1);
$stmt->bindValue(':p2', $p2);
$stmt->bindValue(':p3', $p3);

Passing an array via POST in PHP to be inserted into MySQL

I have a form that allows users to input classes and activities into multiple fields, these fields are declared like this :
label for ="classact">Classes and Activities</label>
<input type = "text" name = "classact[0]" value ="" id ="classact[0]">
<input type = "text" name = "classact[1]" value ="" id ="classact[1]">
<input type = "text" name = "classact[2]" value ="" id ="classact[2]">
When the form is passed this is the code that handles in the insert:
$maininsert = "INSERT INTO `camptest`
(`name`, `city`, `phone`, `photo`)
VALUES
('$_POST[name]', '$_POST[city]', '$_POST[phone]', '$photoinfo')
SET #lid = LAST_INSERT_ID()
";
$classactinsert = "INSERT INTO `class_act`
(`cid`";
for($i = 0; $i < 3; $i++)
{
if(isset($_POST['classact'][$i]))
{
$temp = $i+1;
$classactinsert = $classactinsert . ",`act$temp`";
}
}
$classactinsert = $classactinsert . ")
VALUES
('#lid'";
for($i = 0; $i < 3; $i++)
{
if(isset($_POST['classact'][$i]))
{
$classactinsert = $classactinsert . ",'$_POST[classact][$i]";
}
}
$classactinsert = $classactinsert . ")";
$indata = $maininsert . $classactinsert;
$result = mysql_query($indata);
I realize thats alot of code, but upon filling out the form and submitting this is the query that gets generated:
INSERT INTO `camptest` (`name`, `city`, `phone`, `photo`) VALUES ('Multiple Activities', 'Nowhere', '555-555-1111', 'images/51127f6b06d1e.jpg') SET #lid = LAST_INSERT_ID() INSERT INTO `class_act` (`cid`,`act1`,`act2`,`act3`) VALUES ('#lid','Array[0],'Array[1],'Array[2])
The query is not inserting, but its not throwing back any errors either, even though I have them turned on.
My main question is, what am I doing wrong that is causing the values to act1, act2, and act3 to show up as Array[0], Array[1], and Array[2]?
My secondary question is, am I even going about this the right way? I'm a little new to php and I'm afraid I might be doing this the hard way?
Any help would be appreciated, let me know if you need any additional information.
It does not insert anything, because (among other things) your query string is not being built correctly.
('#lid','Array[0],'Array[1],'Array[2])
The apostrophes are messed up. I'd like to suggest a (in my opinion) cleaner and more structured way to perform your task:
Note: You are obviously working with the mysql_*-stack, so my example is also based on it. But be aware that this is deprecated. Please use mysqli or even better: PDO instead.
<?php
$maininsert = "INSERT INTO `camptest`
(`name`, `city`, `phone`, `photo`)
VALUES
('{$_POST['name']}', '{$_POST['city']}', '{$_POST['phone']}', '$photoinfo')";
//perform the main insert and fetch the insert id
mysql_query($maininsert);
$last_id = mysql_insert_id();
// Put the keys and values of the acts in arrays. We can already
// populate them with the one key-value-pair we already know
$act_keys = array('cid');
$act_values = array($last_id);
foreach($_POST['classact'] as $key => $value) {
//walk through the POSTed acts and add them to the corresponding array
$act_keys[] = 'act'.($key+1);
$act_values[] = $value;
}
//Now build the whole string:
$insert_acts = "INSERT INTO `class_act`
(`" . implode("`, `", $act_keys) . "`)
VALUES
('" . implode("', '", $act_values) . "')";
//and finally perform the query:
mysql_query($insert_acts);
Please also note that this code is highly vulnerable concerning SQL-Injection and should absolutely not be used in production!!! Make sure to either use prepared statements (like with PDO) or/and to sanitize your input properly.
Also, this solution is just my suggestion and one of many ways to do it. But hey, you asked for an opinion :) PHP is very flexible language, so it's easy to get stuff done, but there are many ways to get it done, so there are always chances to pick a hard an ugly one. Other, especially strong typed languages might prevent that by design. But PHP is really easy to learn and I'm sure your code will improve gradually :)
Another thing I've noticed: You don't need to specify the array-keys in your HTML, you just need to make clear that it's an array with [] behind the name. Also, I'm not sure if the id-attributes you using are valid, but you might want use something more simple:
<input type="text" name="classact[]" value="" id="classact1">
<input type="text" name="classact[]" value="" id="classact2">
<input type="text" name="classact[]" value="" id="classact3">
In the next step, you might want to refactor your code a little to make it even more structured and readable. Since you are performing one task, which is 'inserting something into a table', twice, we could also make a resusable function out of it:
<?php
function my_insert($table, $data) {
// We leverage the flexibility of associative arrays
$keys = "`" . implode("`, `", array_keys($data)) . "`";
$values = "'" . implode("', '", $data) . "'";
mysql_query("INSERT INTO `{$table}` ({$keys}) VALUES ({$values})");
return mysql_insert_id(); //This might come in handy...
}
//in order to use this function, we now put our data into associative arrays:
$class_insert = array(
'name' => $_POST['name'],
'city' => $_POST['city'],
'phone' => $_POST['phone'],
'photo' => $photoinfo
);
$class_insert_id = my_insert('camptest', $class_insert); //and pass it to the function
// You can either build the array while looping through the POSTed values like above,
// or you can pass them in directly, if you know that there will always be 3 values:
$activities_insert = array(
'cid' => $class_insert_id,
'act1' => $_POST['classact'][0],
'act2' => $_POST['classact'][1],
'act3' => $_POST['classact'][2]
);
$activities_insert_id = my_insert('class_act', $activities_insert);
There sure is enough room for improvement and optimization - just wanted to show you how awesome PHP can be :-P

Splitting variables from $_POST

I wanted to split my variables from a form, and enter them into a Mysql Database one by one.
My table 4 fields would be: UserID, Status, HowLate, PassFail
In this example below the UserID would be 75 and 76, but can be any # from the user id in the future. I am confused on how I would be able to insert these dynamic variables into the database since I don't know what they will be each time. The only static pattern I have is when I loop through foreach ( $_POST as $key => $value ) any help
$results = print_r($_POST, true);
sample data from form
75=PRESENT
d75=on time
cc75=passed
76=LATE
d76=10 minutes
cc76=failed
I would want to write a query like:
insert into attendance (UserID, Status, HowLate, PassFail) values (76, 'Late', '10 minutes', 'failed')
also think of this as students in a class, so there is 20 records coming back at once
I'm guessing the reason you're doing this is because you're unaware that you can send multidimensional arrays in HTML forms. I suggest an approach such as.
<input name="users[1][userid]" />
<input name="users[1][status]" />
<input name="users[1][howlate]" />
<input name="users[1][passfail]" />
<input name="users[2][userid]" />
<input name="users[2][status]" />
<input name="users[2][howlate]" />
<input name="users[2][passfail]" />
Then in php you can access them in the following manner.
foreach( $_POST['users'] as $key => $user )
{
$userID = $user['userid']; // same for the other fields.
}
Assign your variables (if you are not using PDO, which you should to avoid SQL injection) for example:
$userId = $_POST['userId']; // assuming that is what your field id is from the html form
$status = $_POST['status'];
etc.
Then insert into the database table:
insert into attendance (UserID, Status, HowLate, PassFail) values ($userId, '$status' etc.

Insert multiple same named fields into MySQL Database using PHP

I have multiple fields with names that look like name_$i and I am trying to figure out a way to "on submit", send them all to the database. The thing is that the form is looped and the insert has to be able to adapt to the number of fields in the form. Is there a way to do this???
<?php
$fldcnt = $_POST['fldcnt'];
$i = $_POST['i'];
for ($i = 0; $i < $fldcnt; $i++){
$NAME = $_POST['name_$i'];
$AGE = $_POST['age_$i'];
$ADDRESS = $_POST['address_$i'];
$TELEPHONE = $_POST['telephone_$i'];
$EMAIL = $_POST['email_$i'];
$q_register_new_users = "insert into registration set
NAME = '$NAME',
AGE = '$AGE',
ADDRESS = '$ADDRESS',
TELEPHONE = '$TELEPHONE',
EMAIL = '$EMAIL'";
mysql_query($q_new_products,$connection) or die(mysql_error());
};
?>"
HTML and PHP
You can enter input fields into an array by simply calling the field name[]. Like so:
<input name="name[]" />
You can then use PHP to loop through the fields like so:
foreach($_POST['name'] as $key=>$value){
// Insert the value of the form field into a string or query
// i.e. build the query
$query .= $value;
}
// Then execute the query for each set of fields
The logic above is actually incorrect, but it should give you an idea of what I mean.
MySQL
Your SQL syntax is incorrect, the correct syntax for inserting into a MySQL database is:
INSERT INTO `table` (`field_1`, `field_2`)
VALUES ('value_1', 'value_2')
PLEASE NOTE
The use of the mysql_ functions is hugely discouraged due to there impending deprecation. Instead, most PHP programmers are now using the PDO / SQLite Classes. Whilst these might seem complex, they are actually pretty simple and offer a much more secure way of executing SQL statements.
PDO
SQLite
The syntax for INSERT statement should be like this,
INSERT INTO registration (NAME , AGE , ADDRESS, TELEPHONE, EMAIL)
VALUES ('$NAME', '$AGE', '$ADDRESS','$TELEPHONE', '$EMAIL')
but hte query above is vulnerable with SQL INJECTION, please read the article below to learn how to protect from it,
How can I prevent SQL injection in PHP?
If you are going to keep structure of your code, you need to use double quotes instead of apostrophes
$NAME = $_POST["name_$i"];
or put the variable out
$NAME = $_POST['name_'.$i];
Using array is best way to do this. But if you still want to go head with a counter then you could use
for($i = 0;isset($_POST["name_{$i}"]);$i++)
{
// name found
}
Please note that this code may not be optimal if the name_xx fields are coming from checkboxes, where a user selected items and skipped some in between.
PS. I posted this a comment but it is more suitable as an answer.

Categories