2 for each statements at same time? - php

I recently have been trying to make a way to easily add more fields onto my form without having to go back and add more rows to my database structure. So, to begin working on this, I created a table where the structure is this:
OptionTitle
Option1
Option2
Option3
Option4
Option5
Option6
As you can see, it goes up to 6 options, and OptionTitle is the label name of the form. Then I made another table, one that reflects the users input of the previous table. This table is named usersoption
fid
OptionTitle
Option1
Ok, so FID reflects which form it is referencing to. This way, when displaying the submitted form, it'll pull information from this table where the FID is the same. OptionTitle is the label of the form, and Option1 is the option the user submitted.
Now, onto the form where it actually includes the options to select from. Here is a simplified version of how my code is included:
$query100 = $db->query("SELECT * FROM options WHERE fid='" . $id . "'");
while($row2 = mysqli_fetch_array($query100))
{
echo "
<div class=\"divform\" id=\"optiontitle\">
<label for=\"optiontitle\">$row2[optiontitle]:</label>
<select name=\"option1[]\" id=\"option1\">";
echo "<option value='$row6[option1]'>$row6[option1]</option>";
echo "<option value='$row6[option2]'>$row6[option2]</option>";
echo "<option value='$row6[option3]'>$row6[option3]</option>";
echo "<option value='$row6[option4]'>$row6[option4]</option>";
echo "<option value='$row6[option5]'>$row6[option5]</option>";
echo "<option value='$row6[option6]'>$row6[option6]</option>";
echo "
</select>
</div>
";
}
As you can see, the select name is option1[]. This is so I can have multiple select fields on the same form, and in return this will bring over the multiple difference select fields onto the submitted process. So now onto where my issue is, in the submission process. Here is what I have so far:
foreach($_POST['option1'] as $val){
$val = $db->escape_string($val);
$query30 = $db->query("INSERT `usersoption` SET `gid` = '".$id."', `fid` = '".$fid."', `optiontitle` = 'Where OptionTitle should go', `option1` = '$val'")or die( mysqli_error());
}
As you can see, I can successfully bring the option through a foreach statement. What I can't do, is bring in the OptionTitle. It seems almost unnecessary to bring in the OptionTitle, but it is necessary for the person reading the submitted form to know which option was being submitted. I'm not sure how to carry the OptionTitle over, it seems simple but all my attempts failed miserably. I did some research and one of the suggestions was to create a hidden input with the name and carry it over that way. Here is the addon that would be in the form:
<input type=\"hidden\" name=\"optiontitle[]\" value=\"test\">
This would be added on to the form and then carried over, but the issue is how do I bring it over? I would need to do a multiple foreach statement which does not work. For example, here was what I tried to bring over (it did not work):
foreach($_POST['option1'] as $val) && ($_POST['optiontitle'] as $val2)){
$val = $db->escape_string($val);
$val2 = $db->escape_string($val2);
$query30 = $db->query("INSERT `usersoption` SET `gid` = '".$id."', `fid` = '".$fid."', `optiontitle` = '$val2', `option1` = '$val'")or die( mysqli_error());
}

Have you tried giving your option array a key?
echo "<select name=\"option1[$row2[optiontitle]]\" id=\"option1\">";
Then change your foreach to:
foreach($_POST['option1'] as $title=>$val)

You can use key in foreach to access more array:
Try this code:
foreach($_POST['option1'] as $key=>$val){
$val = $db->escape_string($val);
$val2 = $db->escape_string(isset($_POST['optiontitle'][$key])?$_POST['optiontitle'][$key]:'');
$query30 = $db->query("INSERT `usersoption` SET `gid` = '".$id."', `fid` = '".$fid."', `optiontitle` = '$val2', `option1` = '$val'")or die( mysqli_error());
}

For the hidden input solution: Just do each query as you normally would, but add $_POST['optiontitle']:
foreach($_POST['option1'] as $val){
$val = $db->escape_string($val);
$query30 = $db->query("
INSERT `usersoption` SET
`gid` = '".$id."',
`fid` = '".$fid."',
`optiontitle` = '".$_POST['optiontitle']."',
`option1` = '$val'
")or die(mysqli_error());
}
By the way you should read up on prepared statements. These allow you to sanitise your data before inserting into the database. They are essential to good coding practise.

Related

Php checkboxes to rows

I need to insert each checkbox to row in MySql.
At the moment i am able to catch only one checkbox, but I usually have them 1 - ... who knows how many..
All my checkboxes come from Db like that :
<input type="checkbox" name="lisateenus[]" value="<?php echo $row["id"]; ?>">
On insert it should take the "page id" what is created and after that insert checkbox values to table.
it gets all needed ID-s but it inserts only one checkbox what is checked..
$result = mysqli_query($con,$query);
if($result) {
$last_id = $con->insert_id;
$error = "Uus Teenus lisatud! ". $last_id;
$checkBox = implode(',', $_REQUEST['lisateenus']);
$query="INSERT INTO lisateenuse_seos (p_id, l_id, lisaja) VALUES ($last_id,'" . $checkBox . "','1')";
mysqli_query($con, $query) or die (mysql_error() );
echo "Complete";
} else {
$error = "Teenuse lisamine ei õnnestunud";}
So everything is working exept that it only inserts one row, but 3 rows are checked and should be inserted..
"each checkbox has his own ID (different) only last_id and lisaja have the same id, so each checkbox should be separate row in MySql table (after insert)"
In that case, you actually don't want to implode your checkboxes, but go through with a foreach on them:
foreach ( $_REQUEST['lisateenus'] as $somevalue ) {
$query="INSERT INTO lisateenuse_seos (p_id, l_id, lisaja) VALUES ('$last_id' ,'" . $somevalue . "','1')";
mysqli_query($con, $query) or die (mysql_error() );
echo "Complete";
}
This should insert a new row for each checked checkbox. Using implode actually makes a single string from the whole array, which then you insert only once. With foreach, you send and insert command to the sql for each ( :D ) checked checkbox.
(I added some extra quotes for the good cause.)

how to update a single column of db without deleting its previous data?

i am updating a single column with many values using comma between them. they are working fine. but if update same column from other user the value inserted by previous users deleted. i want to keep values of previous user also with the insertion of new user value. and i also dont want to repeat the same value again because values i m using are unique ids..
// update student list
$venue = ($_GET['venue']);
$district = ($_GET['dis']);
if(isset($_POST['submit']))
//print_r ($_POST);
{
#$std_list=implode(',',$_POST['std_list']);
if(empty($std_list))
{
$error = 1;
$get_value = "Please select you event students.";
}
else
{
//$query = mysql_query("INSERT INTO events (std_list)
//VALUES('".$std_list."')") or die(mysql_error());
$query = mysql_query("UPDATE events SET std_list='".$std_list."' WHERE
id='".$district."' ") or die(mysql_error());
//echo "$msg";
echo "Students list submitted successfully";
}
}
if any query you can ask again. values i am inserting are integers only. Same integer cant be used by two different users.
try this?
$query = mysql_query("UPDATE events SET std_list = CONCAT( std_list, '".$std_list."') WHERE
id='".$district."' ") or die(mysql_error());

Updating a mysql table from an array (HTML form input)

I'm trying to update one row (= ID) of a mysql table from multiple form fields (text fields and text areas). The table looks like this:
ID | Col 1 | Col 2 | Col 3 ... | Col 50
Everything works fine, if I use $_Post[] variables like this
$Name = $_POST['Name'];
$Name2 = $_POST['Name2'];
$sql= "UPDATE Bilder SET Name = '$Name', Name2 = '$Name2' WHERE id = '$ID'";
<form id="InsertData" action="insert-dataset.php" method="post">
<input type="hidden" name="ID" id="ID" value="'.$row->id.'" />
<input type="text" name="Name" value="'.$row->Name.'" /><br />
<input type="text" name="Name2" value="'.$row->Name.'" /><br />
<input type="submit" name="submit" value="Daten eintragen" class="sendbutton" />
</form>
Since I have hundreds of fields I would rather use an array like so:
<input type="text" name="Name[]" value="'.$row->Name.'" />
I found working examples for updating all cells of one column. But I have to update all colums for one ID.
Any help would be appreciated. Thanks in advance!
This is the final result:
$col_result = mysql_query("SHOW COLUMNS FROM Bilder");
$row_result = mysql_query(sprintf("SELECT * FROM Bilder WHERE id = %s", $ID));
if(!$col_result) {
echo 'Konnte Anfrage nicht ausführen: ' . mysql_error();
exit;
}
if ( !empty($_POST) ) {
$aDataSet = array();
while( list( $field, $value ) = each( $_POST )) {
$aDataSet[] = $field . "='" . $value . "'";
}
$update_sql = "UPDATE Bilder SET " . implode( ',', $aDataSet );
$update_sql .= sprintf("WHERE id = '$ID'");
$result = mysql_query($update_sql, $connection);
if(!$result)
{
die('');
}
echo '';
}
mysql_close($connection)
?>
The update query will only include colums that have corresponding input field (input name = column name). Since I have hundreds of input fields, I can spread them over multiple pages using the same code for the update query.
Thank you all for your help.
Probably something like that:
$str = '';
$id = 0;
foreach($_POST['Name'] as $value)
{
$id ++;
$str .= ($str == '' ? '' : ', ').'Name'.$id.' = \''.addslashes($value).'\'';
}
$sql= "UPDATE Bilder SET ".$str." WHERE id = '$ID'";
Note: on this example, your sql fields are Name1, Name2, Name3...
Note2: you should always at least use an addslashes method when pasting a variable inside a sql query, to protect yourself from hackers.
Here is a couple ideas.
Name your fields something useful. Naming them garbage like Name1, Name2 etc is going to bite you on the ass later down the line. Also be nice to the next guy thats going to have to look at this.
If you have a bunch of Meaningful or Unmeaningful fieldnames and don't want to manually type them all out in your code, maybe use the SQL DESCRIBE (http://dev.mysql.com/doc/refman/5.0/en/explain.html) or SHOW COLUMNS command (http://php.net/manual/en/function.mysql-list-fields.php)
Note: untested
<?php
// Get all of the field names
$col_result = mysql_query("SHOW COLUMNS FROM Bilder");
// make sure we could get the colnames from mysql
if(!$col_result) {
echo 'Could not run query: ' . mysql_error();
exit;
}
// Handle a POST
if(!empty($_POST)){
// start preparing the update statement
$update_sql = "UPDATE Bilder SET ";
if(mysql_num_rows($col_result) > 0) {
// make a key = value statement for each column in the table
while($colrow = mysql_fetch_assoc($col_result)) {
// prepare the key = value statement
$update_sql .= sprintf(" %s = %s, ", $colrow["Field"], mysql_real_escape_string($_POST[$colrow["Field"]]));
}
}
// BTW this is going to have a extra "," in it use substr to clear it
$update_sql = substr_replace($update_sql ,"", -2);
// finish off by limiting this statement to only one row
$update_sql .= sprintf(" WHERE id = %s", mysql_real_escape_string($_POST["id"]));
// ACTUALLY RUN THIS STATEMENT
}
if(!$row_result) {
echo 'Could not run query: ' . mysql_error();
exit;
}
    // prepare the sql to fetch the current row we are working on
    $row_result = mysql_query(sprintf("SELECT * FROM Bilder WHERE id = %s", $id));
// Get the row item that you are currently working on
$row = mysql_fetch_row($row_result);
// output all the formfields for the above row
if(mysql_num_rows($col_result) > 0) {
// Go through all of the columns and output the colname from $colrow and the value from $row
while ($colrow = mysql_fetch_assoc($col_result)) {
// The HTML (don't be daunted by that variable-variable http://php.net/manual/en/language.variables.variable.php)
echo '<input type="text" name="' . $colrow["Field"] . '" value="' . $row->{$colrow["Field"]} . '" /><br />';
}
}
?>
lastly, you may be better served by an EAV style of DB where the number of fields for a row is variable. (a fair example with php and mysql: http://www.iwilldomybest.com/2008/08/php-mysql-tip-3/)
Ok, I used preg_replace. This is probably not best practices. The code looks like this and works just fine:
// Handle a POST
if(!empty($_POST)){
// start preparing the update statement
$update_sql = "UPDATE Bilder SET ";
if(mysql_num_rows($col_result) > 0) {
// make a key = value statement for each column in the table
while($colrow = mysql_fetch_assoc($col_result)) {
// prepare the key = value statement
$update_sql .= sprintf("%s = '%s',", $colrow["Field"], mysql_real_escape_string($_POST[$colrow["Field"]]));
}
}
// BTW this is going to have a extra "," in it use substr to clear it
// finish off by limiting this statement to only one row
$update_sql .= sprintf("WHERE id = '$ID'");
$update_sql = preg_replace("/,WHERE/", "WHERE", $update_sql);
There are, of course, security issues. I will fix that. However, this is not that important, since this application is for personal use only. It is not publicly accessible.
I'm pretty new at this kind of thing so I Don't know how safe or effiecnt this is, but it does work.
if ($_POST['Submit']=="Update"){
unset($_POST['Submit']);
$refid=$_POST['refid'];
unset($_POST['refid']);
$update=$_POST;
// Update DB with array
foreach ($update as $col => $val) {
$colsvals=$col."='".$val."'";
$mysql = mysqli_query($db, "UPDATE $tbl SET $colsvals WHERE id='$refid'")
or die('Database Connection Error ('.mysqli_errno($db).') '.mysqli_error($db). " on query: UPDATE $tbl SET $colsvals WHERE id='$refid'");
}
}
I start by cleaning out things I don't want to Updated.
Then I really had to take a sec to make sure I have the double/single quotes, equals, and dots right in the colsvals statment.
But for me The Magic came from realizing I could let the Foreach loop run a new query each time it etterates through the update array.

Inserting Data from dropdown into database with PHP

First I needed a dropdown list that I could update easily so I created a database called
manufacturers where I list manufacturers to be selected in a form.
I finally accomplished this with this code:
<?php
// Connect to the test datbase on localhost
// That's where we created the countries table above
mysql_connect('localhost','##user##','##pass##'); mysql_select_db('wordpress');
// Query the countries table and load all of the records
// into an array.
$sql = 'select * FROM manufacturers';
$res = mysql_query($sql) or die(mysql_error());
while ($rec = mysql_fetch_assoc($res))
$manufacturers[] = $rec;
?>
<form action="select.php" method="post">
<?php
echo '<select name="dropdown">';
foreach ($manufacturers as $c)
{
if ($c['id'] == $_GET['id'])
echo "<option value=\"{$c['meta_id']}\" selected=\"selected\">{$c['meta_value']} </option>\n";
else
echo "<option value=\"{$c['meta_id']}\">{$c['meta_value']}</option>\n";
}
echo '</select>';
?>
<input type="submit" value="Submit" name="submit"/>
</form>
This worked out great I now have a dropdown list that is populated from my
database manufacturers.
Now I need to send this to an existing database call post_meta so that from there I can display the users selection permanently.
I have tried a couple of different options but I am trying to use the following code to send this to my post_meta database.
<?php
$con = mysql_connect("localhost","##user##","##pass##");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("wordpress", $con);
$sql="INSERT INTO wp_postmeta (meta_id, post_id, meta_key, meta_value)
VALUES
('$_POST['meta_id']}','$_POST[post_id]','$_POST[meta_key]','$_POST[meta_value]')";
if (!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
echo "1 record added";
?>
This actually inserts into the database but doesn't record any values.
Please help me figure out what I'm doing wrong.
The proper way to do this is to A: escape all those $_POST superglobals.
and B. Write a query as shown below.
Here's the tabledef for wp_postmeta:
http://codex.wordpress.org/Database_Description#Table:_wp_postmeta
Because meta_id is an auto_increment primary key, you do not provide it, MySQL does.
//$meta_id = mysql_real_escape_string($_POST['meta_id']); <<-- not needed.
$post_id = mysql_real_escape_string($_POST['post_id']);
$meta_key = mysql_real_escape_string($_POST['meta_key']);
$meta_value = mysql_real_escape_string($_POST['meta_value']);
$sql=" INSERT INTO wp_postmeta
(post_id, meta_key, meta_value)
VALUES
('$post_id','$meta_key','$meta_value') "; //<<-- don't forget the quotes!
if ($result = mysql_query($sql)) {
//You can get the new meta_id using:
$new_meta_id = mysql_insert_id($result);
} else {
die ("could not insert ".mysql_error());
}
Do none of your values show up? It looks like you're missing quotes around your key values. For example, shouldn't it be :
$_POST['post_id']
To do a sanity check, just echo your $_POST variables as opposed to doing the insert right away. This will help you figure out if you've got some syntax wrong. Also I'd read Brad's comment and keep it in mind for the future.
Try this query:
$sql="
INSERT INTO wp_postmeta
(meta_id, post_id, meta_key, meta_value)
VALUES
(
'{$_POST['meta_id']}',
'{$_POST['post_id']}',
'{$_POST['meta_key']}',
'{$_POST['meta_value']}'
)
";
And, as people say in comments, this code is very vulnerable, please consider to find better option to pass variables into query.

PHP: Determine whether its a checkbox is checked or not

My checkbox looks like this:
<input type="checkbox" name="activate[]" class="setSetting" value="<?php echo $row["id"]; ?>">
And then i have a foreach:
$activate = $_POST['activate'];
foreach($activate as $a){
echo $a ."<br>";
}
Works fine to get the value out of. But how can i determine if the checkbox has been checked?
$activate = $_POST['activate'];
foreach($activate as $a){
$query_email = mysql_query("SELECT id FROM lp_email_settings ORDER BY id ASC");
while($ro = mysql_fetch_row($query_email)){
$getUserSettings = mysql_query("SELECT * FROM users_email_settings WHERE uID = '$USER' AND eSetting = '$ro[0]'");
if($ro[0] == $a){
if(mysql_num_rows($getUserSettings) != 1){
mysql_query("INSERT INTO users_email_settings (uID, eSetting) VALUES ($USER, $ro[0])");
}
}else{
mysql_query("DELETE FROM users_email_settings WHERE uID = '$USER' AND eSetting = '$ro[0]'");
}
}
echo $a."<br>";
}
Only those checkboxes will be submitted that are considered successful (i.e. checked). That means only the checked checkboxes are available in $_POST['activate'].
And to determine whether a checkbox has been checked, you can use array_search to check whether a particular ID value is in $_POST['activate']:
array_search('12345', $_POST['activate'], true)
And if you change your control’s name to use the ID as key like this:
<input type="checkbox" name="activate[<?php echo $row["id"]; ?>]" class="setSetting" value="<?php echo $row["id"]; ?>">
Then you can simply use isset or array_key_exists on $_POST['activate']:
isset($_POST['activate']['12345'])
array_key_exists('12345', $_POST['activate'])
Edit    As already said in the comments, you should rather iterate the available options and check for each option whether it’s already active and needs to be activated or deactivated. You can do this as follows:
$activate = array_flip($_POST['activate']);
$query = "SELECT t1.id, t2.eSetting
FROM lp_email_settings t1 LEFT OUTER JOIN users_email_settings t2 ON (t1.id = t2.eSetting)
ORDER BY t1.id ASC";
$result = mysql_query($query);
$insert = array();
$delete = array();
while ($row = mysql_fetch_row($result)) {
if ($row[1] === null) {
// option is not set yet
if (isset($activate[$row[0]])) {
// option needs to be set
$insert[] = $row[0];
}
} else {
// option is already set
if (!isset($activate[$row[0]])) {
// option needs to be unset
$delete[] = $row[0];
}
}
}
if (!empty($insert)) {
$query = "INSERT INTO users_email_settings (uID, eSetting)
VALUES ($USER, " . implode("), ($USER, ", $insert) . ")";
mysql_query($query);
}
if (!empty($delete)) {
$query = "DELETE FROM users_email_settings
WHERE uID = $USER AND eSetting IN (" . implode(", ", $delete) . ")";
mysql_query($query);
}
The first query will select a left join of all available options and the already active options. So the result set is the ID of the option in the first column and the second column is either NULL if the options is not active or otherwise again the ID. So if there are three options (e.g. 1, 2, and 3) and only the options 1 and 3 are already set, the result should look like this:
id | eSetting
----+----------
1 | 1
2 | NULL
3 | 3
So if $row[1] is null (inactive option), the ID in $row[0] is added to the $insert array if the corresponding option was set in the request ($activate[$row[0]], the keys/values are flipped to have a direct access). The same is done for those options that are already active but were not set in the request.
At the end the collected options in $insert are inserted and those in $delete are removed.
If you get a value it has been checked, otherwise you get nothing...
Here is a pretty good tutorial explaining how it works: http://www.html-form-guide.com/php-form/php-form-checkbox.html
Checkboxes will only be submitted at all if they are ticked. If they are unticked, PHP won't see them in $_POST.
I assume since you're using square brackets (ie activate[]) that you have more than one of them all with the same name. This will make it very hard to tell which ones were ticked, since you'll just get an array of the ones which were ticked; you'll know how many, but not which ones.
To get around this, you either need to give them all different names, or specify the array key for each one in the HTML code - ie name="activate[4]" or name="activate[bob]". Depending on the context, this could be an ID of the data you're activating, or the name of the feature, or anything else you decide, as long as it's unique for each field.
You will then still get the array only containing the ones which were ticked, but you will be able to tell which ones they were in your foreach loop by looking at the array key.
Hope that helps.
You can check against each submitted value ($activate) to see if it does actually contain anything/fits your criteria:
$activate = $_POST['activate'];
foreach($activate as $a){
if($activate){
echo $a ."<br>";
}
}
Though the array should only contain those values checked.

Categories