Multidimensional array to MySQL - php

I've got a form like so:
Question: <input type="text" name="question[][text]" id="question" />
Type:
<select name="question[][type]" id="type">
<option value="1to5scale">1 to 5 scale</option>
<option value="freetext">Open text</option>
</select>
This gets repeated depending on how many items the user wants (cloned through jquery). And my php to action the form contains:
foreach ( $_POST['question'] as $key=>$question )
{
if ($key >= 1) {
$question_text = $question['text'];
$type = $question['type'];
$query = " INSERT INTO questions (question_text, survey_id, type) ".
" VALUES ('$question_text','$survey_id', '$type')";
mysql_query($query) or die('Error ,query failed');
}
}
Each question has a text item and a type item. However in the DB it's adding one row per question item (if that makes sense...), rather than one row per complete question. Any ideas where I'm going wrong, it's quite hard to debug forms I'm finding...

Change the form element name from question[][type] to question[type][]. What this form does is add to the question array for each form element ([] means add a new array element).
As the comment implies, make sure you sanitize the input.

Related

How to parse an array into variables (PHP)?

For the life of me I cannot get this to work. I've looked at many articles on stackoverflow so if you could help that would be wonderful! I am working on a form submission for a client. They want to be able to select multiple values from a dropdown, which in turn I will pull from a database to get their query results.
<form id="test" action="results.php" method="POST">
<select id="role" name="role[]" multiple>
<option value="Student">Student</option>
<option value="Faculty">Faculty</option>
<option value="Alumni">Alumni</option>
</select>
<?php
$query="SELECT City FROM Cities";
$result = mysqli_query($link, $query);
echo '<select name="city" id="city" multiple>';
while($r = mysqli_fetch_assoc($result)){
echo '<option value="'.$r['City'].'">'.$r['City'].'</option>'; }
?>
</select>
<input type="submit"/>
</form>
//results.php
$results=array();
$results[] = $_POST['role'];
$results[]= $_POST['city'];
echo "<pre>";
print_r($results);
echo "</pre>";
**How do I obtain all the values from the array and parse it into separate variables so I can use the variables in a SQL statement? Here is my output: **
Array
(
[0] => Array
(
[0] => Faculty
[1] => Alumni
)
[2] => Adams
)
Thanks so much for any help! :) And if there is a better way to do this, let me know.
[EDIT] : This code is wild open to SQL Injection , Please don't use it.
One submit options i already have in the question and one i created
dummy submit options for city, run this code in the different file,
than select different different options, and click on submit button,
to check how our query is getting built
Please read the note first and make sure you read the comment in the code, as they are more important than the code
Note 1-> in short you want to run the query, according to the selected options by the user,
make sure you read the comment to understand the logic, comments are more important than the code it's self,
Note 2-> and more thing i did not realize, you may be storing your value in different different table, if that's the case, code will change little bit, but basic shell will remain the same
Note 3-> To achieve the out come which you want to achieve, you basically have to create your query according to the set options, and than use IN keyword and you are good go,
Note 4-> I added echo statement, so you can see stage by stage how our query is developing, i added the comment, if you want see just remove the comment, I did not add the comment in the last echo so you can see the ready to use query string
Note Again-> one submit options i already have, one i created by my self, so you can see what happening, and you it going to work out for you.
as you said in the comment you may have 12 field, in your form, if that's the case, use this code, because lets say if you have to change
some thing in the future, and you have to change at tweleve places,
you will make mistake like miss some thing, or use the wrong variable
or some thing else, with this code, you have to change it one place,
and it will get apply to 12 or 24 places, number of places does not
matter,
and one more thing, it will better if you wrap this php code inside the function, the reason is lets say you have form on some other page, and you need same functionality only thing you have to do than, just call the function, and in the future if you have change some thing, just change the function code
I am giving you example on your code why it is better to wrap this in a function, lets say your table name are different than the given selected name in your form or you decided to hole values in different different table, than you have to change the code, if you wrote this twelve times or each form, and than you have to change it, than you are in big trouble, but if you use this code as function for different different form, you just have to do some changes in function or in here, and will get applied everywhere, in short chances of you screwing up some thing is just not their, so hope fully this will help you
SideNote -- one more thing i want to say, the reason this solution look big, is because of note, form and comment, if you count the php code line, with out the last echo statement, it actually only 10 lines of php code, so dont get afraid, becuase it's look big
<form id="test" action="" method="POST">
<select id="role" name="role[]" multiple>
<option value="Student">Student</option>
<option value="Faculty">Faculty</option>
<option value="Alumni">Alumni</option>
</select>
<select id="city" name="city[]" multiple>
<option value="London">London</option>
<option value="Paris">Paris</option>
<option value="New York">New York</option>
</select>
<input type="submit">
</form>
<?php
//creating variable and saying all the post request is equal to this variable
$selected_options=$_POST;
foreach($selected_options as $key=>$option){
$countValue = count($option);
for($i=0; $i<$countValue; $i++){
/*
* start adding the value seperated by coma, remember again it going to
* be on extra coma so we have to remove it.
*/
$queryString_start_with_coma .= ",$option[$i]";
}
/*
* come out of loop, and now remove that extra coma
*/
$queryString_remove_extra_come= preg_replace("/,/", "", $queryString_start_with_coma, 1);
/*
* start building your query, use variable $key, just check the line below,
* you will understand where and why i am using variable $key.
*/
$query_string_with_and .= " AND $key IN($queryString_remove_extra_come)";
/*
* now unset the variable, this line is very important, so please also check
* your out come without this line,
* what i am simply doing is emptying the variable, if you dont
* do it, it will add the value in the existing value, which i dont want, what
* i want when the loop run for the second selected options, i want my variable
* to be empty, so i can create new string
* you will understand more if you remove this line and compare your two outcome
* Note: you dont have to unset if you dont want to, but you have empty the
* variable, you can also do by creating a empty string, do what ever you want
* to do, just make sure the variable is empty for the second loop
*/
unset($queryString_start);
}
$query_string_second_part_ready = preg_replace("/AND/", "", $query_string_with_and, 1);
//echo "$query_string_second_part_ready<br>";
$query_string= "SELECT * FROM table_name WHERE ".$query_string_second_part_ready;
//see how your query look like
echo $query_string;
It sounds like you want to be able to build a query based on the data submitted by the user. This may be a little more complex if you have multiple tables, but the basic idea is to use the input names with the fields, assemble the query from them, prepare the statement and bind the parameters.
Name the inputs the same as the database fields they match to
// Identify which database fields can be searched
// These names must match the names of the inputs
// Each name has a type which will be used later
$databaseFields = [ 'city' => 's', 'name' => 's', 'grade' => 'i' ];
$databaseFieldNames = array_keys($databaseFields);
// Set up the beginning of the query
$query = 'SELECT * FROM some_table WHERE ';
// Initialize an array to use to store fields to be searched
$where = [];
// Loop through all the post data
foreach ($_POST as $name => $value) {
// If the name is in the database fields list, add it to the query
if (in_array($name,$databaseFieldNames)) {
$where[] = $name;
}
}
// Add all the requested columns to the where
if (!empty($where)) {
$query .= ' '.$where[0].'=?';
array_pop($where);
foreach ($where as $name) {
if (is_array($_POST[$name])) {
// Use any to check for multiple possible values
$query .= ' AND '.$name.' = ANY (?)';
} else {
$query .= ' AND '.$name.'=?';
}
}
} else {
// Avoid an empty WHERE which will cause an error
$query .= ' TRUE';
}
$stmt = mysqli_prepare($query);
/* Bind parameters */
foreach ($where as $name) {
// $_POST should be validated here
if (is_array($_POST[$name])) {
// Arrays are imploded to work in an ANY
$value = "'".implode("','",addslashes($_POST[$name]))."'";
} else {
// Other values are used as sent
$value = $_POST[$name];
}
$type = $databaseFields[$name];
$stmt->bind_param($type,$value);
}
$stmt->execute();

Retrieve previously selected chosen dropdown subject value(s)

I'm having a problem with the coding because I cannot get the chosen dropdown menu multi-select Version 1.4.2 to retrieve the previous selected subject value(s) from the dropdown menu when I click it again to activate it.
I'm using two different tables with one field name for each one, so I'm trying to match the t_subjects field name(s) in the member table with the name field name in the category table and if there is a match, that subjects field name will result in <option value='subject_name' selected >subject_name</option> and where there is no match it will be <option value='subject_name'>subject_name</option>
This is what I'm trying to get to happen for those subjects that match when I click it anytime after the first post.
There are forty-two subjects that are dynamically loaded in a chosen multi-select dd menu option.
I have no problem with posting the subject(s) names to the database using the implode method.
if(isset($_POST['submit']))
{
$subjects = implode(',', $_POST['subjects']);
But, if I open the page again to make another post with the subjects field name blank, I get an error that says:
Warning: implode() [function.implode]: Invalid arguments passed in...
So, you can see why I need to have the previous subject(s) values selected when I activate it again. Here is the code for the chosen dd menu.
<tr>
<td width="32%">Subjects:</td>
<td width="68%">
<input type="radio" name="utype" id="sutype" value="s" />Subject(s)
<div id="studspan" style="display:none;">
<strong style="vertical-align:top;">Select Subject(s) :</strong>
<select name="subjects" id="subjects" data-placeholder="Select Subject(s)" style="width:350px;" multiple class="chosen-select">
<?php
$cat_sele = mysql_query("SELECT * FROM category");
while ($cat_row=mysql_fetch_array($cat_sele)) {
if($_POST['subjects'] == $cat_row['name']) $s = " selected"; else $s = "";
echo "<option value='{$cat_row['name']}'$s>{$cat_row['name']}</option>";
}
?>
</select>
</div>
The problem seems to be in this part of the code: if($_POST['subjects'] == $cat_row['name']), because when I replace $_POST['subjects'] with 'Accounting' to check it, it will show that Accounting has been selected when I activate it again, but if I add another subject name, it will show all of the subjects as selected. I even tried if($_POST['t_subjects'] == $cat_row['name']) as well as ("SELECT name FROM category"), but they didn't work either. So any help to help this teacher make it work will be very appreciative.
I have also included other parts of the code that are involved in the process too.
elseif($_SESSION['user_type']=="m")
{
$getuser_sele = "select * from member where member_id = '".$_SESSION['ses_id']."'";
$getuser_qry = mysql_query($getuser_sele);
$getuser_row = mysql_fetch_array($getuser_qry);
$subjects = stripslashes($getuser_row['t_subjects']);
=============================================================
elseif($subjects=="" && $_SESSION['user_type']=="m")
{
$error="Please Enter Preferred Subjects";
}
=============================================================
elseif($_SESSION['user_type']=="m")
{
$qr=mysql_query("update member set
t_subjects='".addslashes($subjects)."',
=============================================================
<body onload="$('.chosen-select').show();
$('.chosen-select').chosen();">
=============================================================
<script type="text/javascript">
$("#sutype").click(function () {
$("#studspan").show(1000);
$('.chosen-select').chosen('destroy');
$('.chosen-select').show();
$('.chosen-select').chosen();
});
</script>
<script src="js/chosen.jquery.js" type="text/javascript"></script>
=============================================================
Update:
Tristan, it works but it shows all of the subject names as selected and de-seleted in the choice list, which is not what I want to happen. I also got the following error in the source code for each of the subject names. I'm just showing the first one below.
<b>Warning</b>: array_search() expects parameter 2 to be array, null given in <b>/home/.../.../edit.php</b> on line <b>2784</b><br /> <option value='Accounting' selected>Accounting</option><br />
I think the problem is how the table/fields are setup in the dbase.
Here is what should happen based upon the first row of the t_subjects. If I log in as member 1 and open the chosen dd menu, Accounting,Athletics,Art from row one of t_subjects should be selected while the rest of the subject list would be non selected in the chosen dd menu. This would happen for each member's row t_subjects they have listed when they initially posted them the first time.
all images to show what I'm talking about.
Using <select name="subjects" ... multiple> will only send post data for one selection. You need to use <select name="subjects[]" ... multiple> to send all selected options in the post data.
Then $_POST['subjects'] will be an array so you will need to search the array for the category name.
$cat_sele = mysql_query("SELECT * FROM category");
while ($cat_row=mysql_fetch_array($cat_sele)) {
if(array_search($cat_row['name'], $_POST['subjects']) !== false) $s = " selected"; else $s = "";
echo "<option value='{$cat_row['name']}'$s>{$cat_row['name']}</option>";
}

Using concatenated variables individually for database fields

I am new to stackoverflow and am after a little help. I have already tried searching for what I am about to ask, but cannot find any relevant topics, so here goes:
I have a PHP page, that gets a list of venues and it's town/city from a table within a MySQL database, which I have then concatenated to populate a dropdown, e.g. each <option> will display "[venue], [town/city]".
What I am trying to do is when the user selects one of the options, I want to store the [venue] and [town/city] as separate fields in another table within the MySQL database.
I would really appreciate any help.
More details might be needed. For instance do you need to know how to insert records on database? or are you also having trouble getting values of option tag?
But from what I understood:
First remember to set value attribute of option tags:
<option value="venue,town">venue,town</option>
Then after submitting the form, you can slice the returned string.
Assume you stored "venue,town" inside a variable named $str
$results = explode(",",$str);
$results will be an array with two elements. $results[0] contains "venue" and $results[1] contains "town"
I am not sure how much it helped but you can give more details and I'll get back
I think the best way is to put the datarecord ids (primary key value) into the value attribute of the <option> tags, then on the server side requery the data of the selected id from the database. This way your form can't be manipulated with unwanted data.
To be more clear, I would do it like in this simplified semi pseudocode:
<?php
$action = isset($_GET['action']) ? $_GET['action'] : null;
if($action == "save") {
$id = $_POST['venue'];
if(!empty($id)) {
/* fetch data belonging to $id from database and then save venue and town/city
as separate fields in another table */
}
}
/* fetch all data for the selectbox from the db and store it in $data */
?>
<form action="?action=save" method="post">
<select name="venue" size="1">
/* iterate through $data and create $id and $caption */
<option value="<?php echo $id; ?>"><?php echo $caption; ?></option>
/* iteration end */
</select>
<input type="submit" value="save" />
</form>

submit all users values from form into db

This gives lists all people in the db and give a drop down for each one of them i want to make it so when i hit one submit button it enters individual values for each person.
so if you make yes for bobby no for mark and yes for dustin you can the pres submit and it will enter that for there values
$results = mysql_query("SELECT * FROM `$tabeluser` WHERE buss='$buss' ORDER BY id DESC LIMIT 1");
while($rows = mysql_fetch_array($results) )
{
fn = $_POST['firstname'];
echo $fn;
?>
<form>
<select name="check">
<option>no</option>
<option>yes</option>
</select>
<?php
<input type="submit" name="submit">
?>
<form>
<?php
}
mysql_query("INSERT INTO `$fn` (buss) VALUES ('$_POST[check]')");
First of all, you create a <form> and a submit button for each of the records you have. That is wrong, since you want to update multiple values at once.
What it should look like would be:
<form>
<?php
while($rows = mysql_fetch_array($results)) {
print '<select name="check[]"> .. </select>';
}
?>
<input type="submit" name="submit" />
</form>
Secondly, your code is formatted as if you are expecting to get $_POST[check] right after sending the code to the browser. That is not how PHP works. You need to separate the logic of having posted values, before printing the actual page contents. PHP is server side, which means that it won't get any data, unless the script is called with it from the beginning. So, that should look something like:
<?php
if (isset($_POST["check"])) {
// handle posted data.
}
else {
// show form
}
// or show form here, without an else, if you want to always show a form,
// even when you have posted values.
?>
Last but not least, you need to find a way to know which posted value belongs to each of your records. The way you have it now (<select name="check">') it will just return you one single value.
If you write it the way I intentionally did above (`) you will get all values, but still you won't be able to easily recognize which value is for each record.
Instead, you may want to do a final result of something like:
<?php
// get mysql records into an array (say $my_array)
if (isset($_POST["submit"])) {
foreach($my_array as $record) {
if (isset($_POST["select_of_id_".$record["id"])) {
// insert additional value into db
}
}
}
print '<form>';
foreach($my_array as $record) {
print '<select name="select_of_id_'.$record["id"].'">';
print '<option value="0">no</option><option value="1">yes</option>';
print '</select>';
}
print '<input type="submit" name="submit"/>';
print '</form>';
?>
Changes required in your code :-
<select name="check[]">
<option value="<?php echo $userId;?>_0">no</option>
<option value="<?php echo $userId;?>_1">yes</option>
</select>
You should make changes in you DB It help to easy maintaing your data.
Create new table where you can save multiple user check data with respective Post
for e.g post_id user_id check
101 111 0
101 112 1
How you can store data from you html
In you post array you will get check array in which you will get multiple check value like this
101_0 if no selected and 102_1 if yes selected. Now you need to explode this value.
$_POST['check'] = array(0 => `101_0`, 1 => 102_1);
Inside loop you can extract userid and respective checked value.
for e.g
$checked = explode('_','101_0');
$userId = $checked[0];
$check = $checked[1];

Problem With PHP/HTML Dropdown Box Code (selected value)

I wrote some PHP code that will allow me to create an html dropdown box, and then choose what should be the selected value. The code is:
$role_drop = "<select name='role'>";
$role_drop .= "\r\n<option value='Resident Assistant'>Resident Assistant</option>";
$role_drop .= "\r\n<option value='Community Assistant'>Community Assistant</option>";
$role_drop .= "\r\n<option value='Head RA'>Head RA</option>";
$role_drop .= "\r\n</select>";
$result = mysql_query("SELECT role FROM users");
if (#mysql_num_rows($result)) {
while ($r=#mysql_fetch_assoc($result)) {
$role = $r["role"];
$role_drop = str_replace(">$role</option>", "selected=\"\" >$role</option>",$role_drop);
echo $role_drop;
}
}
In reality, this code has a bunch of HTML mixed in, but here is all of the PHP. When I run it, it seems to work. However, let's say the query returned 4 dropdown boxes with roles (from 4 users), and I were to Edit, or select, a new role for the 2nd dropdown box returned (with an UPDATE query), then when the page refreshes, all of the roles including and AFTER the dropdown box I updated will display their selected values as the new one I selected in the 2nd dropdown box.
And it's not that the values in the actual database are wrong, they are just displaying the wrong selected value. Here is the source code for the 3rd dropdown box after I select a new value for the second one:
<select name="role">
<option selected="" value="Resident Assistant">Resident Assistant</option>
<option value="Community Assistant">Community Assistant</option>
<option selected="" value="Head RA">Head RA</option>
</select>
So, it seems its selecting the correct value (Resident Assistant), however its ALSO selecting "Head RA", which is what I changed the prior dropdown box to.
It's very strange, and I have NO idea why this is happening. Any ideas?
Thanks!
It's because you're updating $role_drop each time, so all the previous changes are going to show up in subsequent dropdowns. I'd change the loop to something like this:
if (#mysql_num_rows($result)) {
while ($r=#mysql_fetch_assoc($result)) {
$role = $r["role"];
$temp_role_drop = str_replace(">$role</option>", "selected=\"\">$role</option>", $role_drop);
echo $temp_role_drop;
}
}
That way you're not overwriting your original dropdown markup.
Nuts - forgot to escape my code. I meant, "It's just <OPTION VALUE="foo" SELECTED>".
Dunno if this helps, but according to the HTML spec you shouldn't be passing a value along with the SELECTED attribute of each OPTION. It's just .

Categories