Update in PDO/SQL with a variable number of variables :) - php

I have a code that retrieves all the input data sent in a form. If the form had only 2 fields filled out, the PHP gets the value for only those 2 fields (the unchanged fields in the form are not submitted).
Then I would like to UPDATE a SQL table for those fields that I have retrieved with my PHP code. Here is where I am lost. I would need to specify in the SQL only the fields that I have received from the form, but this is variable. Maybe I received only 1 field, maybe I received 7 of the fields...
Here is my code:
if (isset($_POST) && !empty($_POST)) {
echo $internalImage;
foreach ($_POST as $key => $value)
{
echo "Field Name: ".htmlspecialchars($key)." | Value: ".htmlspecialchars($value)."<br>";
}
}
What would you suggest?

You could construct your query like this:
$values=array();
//this will be an array of possible fields that are in your table
$possible=array('field1', 'field2', 'field3');
$i=0;
$len=count($_POST);
$query='update table_name set ';
foreach($_POST as $key => $value){
$k=htmlspecialchars($key);
$v=htmlspecialchars($value);
if(in_array($k, $possible)){
$query .= $k .' = ?'; //placeholder for a value
$values[]=$v; //append values to an array for later use
if($i < ($len-1)) $query .= ', ';
$i++;
}
}
$query .= 'where table_id = ?';
$values[]=$table_id; //forgot that, append id of a row you are to update.
and then prepare and execute the query:
$db->prepare($query);
$db->execute($query, $values);

Related

Send only filled inputs values to database via SQL

I have dozens of inputs in an HTML table one can use to enter numerical values. When submit button is pressed all inputs values are added to their corresponding column in the SQL table via post method. Value of <input name="A1> will be sent to column A1 in SQL table, <input name="A2> to column A2, and so on.
I'm currently using something like this (but with dozens of parameters) to insert data in my table :
$sql = "INSERT INTO all_stats_table (A1, A2, A3) VALUES ($A1, $A2, $A3)";
Problem with this approach is that every input needs to be filled or it will result in an SQL error. I initially used php to set all empty inputs value to 0 before sending everything to database, but I don't think this method is the most efficient way to go.
I would rather like to dynamically check which inputs are actually filled and only send their values to the table instead of converting every empty input value to 0 and having to send everything to the database.
I've already set all default values to 0 in SQL, but I don't know how to only send filled input values via SQL. I tried using a php foreach loop but I'm definitely having trouble finding the right SQL syntax.
Is what I'm trying to do possible ? If not, what would be the best practice to make this process more efficient ?
Thank you for your help
EDIT : attempt to adapt akash raigade's great solution to non-numbered SQL columns :
HTML :
<input name='name'>
<input name='address'>
<input name='age'>
PHP :
$Field_list = array ('name','address','age');
$field_string = '';
$input_string = '';
foreach ($_POST as $userInfo=>$userInfo_value) {
if (isset($userInfo)) {
if ($field_string == '') {
$field_string = $field_string.$userInfo; //problem here ?
$input_string = $userInfo_value; //problem here ?
}
else {
$field_string = $field_string.','.$userInfo; //problem here ?
$input_string = $input_string.','.$userInfo_value; //problem here ?
}
}
}
$sql = "INSERT INTO protocole_test (".$field_string.") VALUES (".$input_string.")";
echo $sql ; //check query formed
[Upgraded version]
Basic idea is that we keep NAME attribute of INPUT same as table column-name where it is gonna be stored.Then with help of input tag name and value which are filled we prepare SQL statement which have only required (FILLED) columns and values.
For given example consider following MYSQL table :
sr.no.|name|age|gender
CODE [Tested]:
<input name="name" >
<input name="age" >
<input name="gender" >
<input type='submit'>
<?php
$field_string ='';
$input_string='';
foreach ($_POST as $userInfo=>$userInfo_value){
if($userInfo_value !=''){
echo $userInfo."->".$userInfo_value;
if ($field_string == '') {
$field_string = $field_string.$userInfo;
$input_string = $userInfo_value;
}
else {
$field_string = $field_string.','.$userInfo;
$input_string = $input_string.','.$userInfo_value;
}
}
}
$sql = "INSERT INTO protocole_test (".$field_string.") VALUES (".$input_string.")";
echo $sql ; //check query formed
?>
[original answer]Have a look at following code :
<input name='a1' id='input_for_name'>
<input name='a2' id='input_for_class'>
<input name='a3' id='input_for_seat.no'>
.
.
<input name='an' id='input_for_n'>
Now
<?php
//you must be having field list to be inserted i.e
//INSERT INTO all_stats_table >>>(A1, A2, A3)<<< VALUES ($A1, $A2, $A3)
//A1,A2,A3 is field list here
//so save them into an array.
$Field_list = array ('A1','A2','A3',.......'An');
//Now get which input_field is inputted by :
$i=0;
$field_string = '';
$input_string = '';
for($i<n){
if(isset($_POST['a'.$i])){
if ($field_string == ''){
$field_string = $field_string.$Field_list[$i];
$input_string = $_POST['a'.$i];
}
else {
$field_string = $field_string.','.$Field_list[$i];
$input_string = $input_string.','.$_POST['a'$i];
}}}
$sql = "INSERT INTO (".$field_string.") VALUES (".$input_string.")";
//to check query formed
echo $sql ;
?>
Explanation :
We check which input field is FILLED , if it is field we add its FIELD into FIELD LIST and ITS VALUE in INPUT LIST finally we GENERATE SQL STATEMENT.
Just check if they are not defined or empty, and if so, define them.
if ( (!isset($_POST['A1'])) || (empty($_POST['A1']) ){
$A1 = '0';
} else {
$A1 = $_POST['A1'];
}
I'm not able to test this and it may need some debugging, but you could create a function, then call the function for each input. Something like...
function chkinput($input){
if ( (!isset($_POST[$input])) || (empty($_POST[$input]) ){
$$input = '0';
} else {
$$input = $_POST[$input];
}
return $$input;
}
// You could potentially loop through the post array
// but here I just call the function once per input
chkinput('A1');
chkinput('A2');
...
chkinput('A12');
You loop through the $_POST array and check if it has a value. If it does concatenate it to an variable. Like this:
$fields = "";
$values = "";
foreach($_POST as $key=>$value){
if($value != ''){
if($value != end($_POST)){
$fields .= $key . ", ";
$values .= "'" . $value . "', ";
}else{
$fields .= $key;
$values .= "'" . $value . "'" ;
}
}
}
$sql = INSERT INTO protocole_test ($fields) VALUES ($values) ;
Your SQL would look like :
INSERT INTO protocole_test (A1, A2, A3) VALUES ('A1', 'A2', 'A3')

How to block inserting empty strings in MySQL

I have this update statement (PHP code):
$sql1="UPDATE `utilizatori` " .
"SET utilizator='$utilizator', parola='$parola1', nume='$nume', " .
"`prenume='$prenume', varsta='$varsta', localitate='$localitate'` ";
WHERE parola='".$_SESSION['parola']."'";
This will update some MySQL table fields via an html form. The user wants to change just his name for instance. He completes just name field, then he presses submit. The data is sent into the table with the UPDATE statement above.
The problem is that it also updates the table with blank values that user didn't complete. I don't want the blank values to be added.
How can I block the blank values to be sent into the table?
If you really wanted to do this in the update, you can change the set statement to something like:
set utilizator = (case when '$utilizator' <> '' then '$utilizator' else utilizator end),
. . .
This will use the previous value if the new one is blank.
You can also do this at the application level by just updating the fields that have changed.
And, you should use parameterized queries rather than directly substituting values into a string. That is another issue, though.
You can do two things to solve this issue. One is to preload the data in the form. So when the user change his name, the other fields are already loaded with the original information.
The second option is to create an update query based on the fields have a value.
Example of option 1:
<?php
//
//GET THE DATA FROM A SELECT QUERY HERE
//FOR EXAMPLE: $sql = "SELECT * FROM `utilizatori` WHERE parola='".$_SESSION['parola']."'";
//Put the data of the sql row in a variable e.g. $sqlRow.
?>
<!--Use variable in your form!-->
<form>
...
...
<input name="nume" value="<?=$sqlRow['nume']?>"/>
<input name="utilizator" value="<?=$sqlRow['utilizator']?>"/>
...
...
</form>
Example of option 2:
<?php
//Catch post data
if($_POST)
{
$updateString = "";
foreach($_POST as $inputField => $inputValue)
{
if($inputValue != "")
{
$updateString .= $inputField." = '".$utilizator."',";
}
}
//Strip last ,
$updateString = substr($updateString,0,-1);
if($updateString != "")
{
//Your query would be
$sql1 = "UPDATE `utilizatori` SET ".$updateString." WHERE parola='".$_SESSION['parola']."'";
}
}
?>
$updateClauseArr = Array();
foreach($_REQUEST as $key => $val){
if(is_numeric($val)){
$updateClauseArr[] = '$key = '.(int) $val;
}else{
$updateClauseArr[] = "$key = '".htmlentities($val,ENT_QUOTES,'UTF-8')."'";
}
}
if(sizeof($updateClauseArr) > 0){
$updateSet = implode(',' ,$updateClauseArr);
$sql1="UPDATE `utilizatori` SET ".$updateSet." WHERE parola='".$_SESSION['parola']."'";
}
See what field values have been submitted by the user. then iterate in a loop for the fields that have value to make variable to be concatenated to the update query.

updating each row with previous values plus current values

sorry for the complicated heading.i am doing learning php and got stuck.i have a database table table_name
id(primary key) name ip
1 a 192.168.0.1,192.168.0.5,171.87.65 //separated by comma's
2 b 192.168.0.1,175.172.2.6,164.77.42
now i want to add an array of values ip[0] and ip[1] coming from a two different text-area to the end of the ip's of each name and just updating the ip column of each row.so it will just append new values with previous one.
name a<textarea rows="4" cols="40" name="ip[]"></textarea>
name b<textarea rows="4" cols="40" name="ip[]"></textarea>
<input type="submit" />
this is how its inserted
if(isset($_POST['submit'])) {
$ip_details = $_POST['ip'];
$values = array(
array('id' => '"1"', 'name' => '"a"', ip => '"'.$ip_details[0].'"'),
array('id' => '"2"','name' => '"b"', ip => '"'.$ip_details[1].'"'),
);
$columns = implode(', ', array_keys($values[0]));
foreach($values as $value) {
$value = implode(', ', $value);
$statement = "INSERT INTO `center_listt` (id,name,ip) VALUES ($value)";
$res=mysql_query($statement);
echo "success";
}
}
i need to update each rows of namea and b with new values coming from text-area with previous values.
i am thinking of array_push after fetching ip from table in while loop but could not really do it.warning: array_push expects parameter 1 to be array integer given its because the $row['ip'] fetched in while loop is not valid array which array_push expects.
and it will only add new values in different new rows each time which i don't want.can someone please help what to do.
<?php
if(isset($_POST['submit'])) {
//print_r($ips); die;
$i = 0;
foreach($_POST['ip_details'] as $ipaddr) {
$ips[$i] = $ips[$i].$ipaddr;
$i++;
}
$r = 1;
foreach($ips as $ip){
//echo "UPDATE center_listt SET ipdetails = '$ip' WHERE `id_center` = '$r'"; die;
if(mysql_query("UPDATE center_listt SET ipdetails = '$ip' WHERE `id_center` = '$r'")) echo "IP Address Updated <br />";
else echo 'error occurred';
$r++;
}
}
$sql="select * from center_listt";
$res=mysql_query($sql);
if(!$res) {
die('could not connect'.mysql_error());
}
while($row=mysql_fetch_assoc($res))
{
echo $row['ipdetails']; }
?>
its a bad practise to insert form values from array.you can fetch it from db bcoz if in future you want to add new form values you need to rewrite again with array values while fetching from db will only need you to insert new values in db.
my query will add ip's in your specific column in a single row only updating the ip with new values.
You could do this:
$values = array(...); // WARNING: escape `$ip_details` here!!
$to_insert = array();
foreach($values as $row) {
$to_insert[] = "(".implode(", ",$row).")";
}
$statement = "insert into `center_listt` (`id`, `name`, `ip`)
values ".implode(", ",$to_insert)."
ON DUPLICATE KEY UPDATE `ip`=concat(`ip`,',',values(`ip`))
";
mysql_query($statement);
This will perform a multi-insert (far more efficient than individual queries), and when you try to insert the same ID twice it will instead concatenate the values.
It should be noted that this is bad database design, though :p

How to use foreach to create an array and later update a database

I have a dynamic form that populates a questionnaire rating scale from information saved in my database. Each rating consists of a "selection" and a "definition". A scale can consists of any number or ratings. Here is an example of a 5 rating scale:
Strongly Agree = I strongly agree with this statement.
Agree = I agree with this statement.
Neither Agree nor Disagree = I neither agree nor disagree with this statement.
Disagree = I disagree with this statement.
Strongly Disagree = I strongly disagree with this statement.
Once the form is populated, the user can edit any of the selections or definitions. My form populates just fine, but I cannot figure out how to correctly populate the POST data into an array if the user submits a change or use that array to edit the information in my database.
Here is my PHP:
if(isset($_POST['submit'])){
$fields = "";
$values = "";
foreach($_POST as $key => $value) {
$fields = mysql_real_escape_string($key);
$values = mysql_real_escape_string($value);
$entry .= "[". $fields . "=" . $values . "]";
//Here is the start of the query that I'm building
//$query = mysql_query("UPDATE `pd_selections` SET `pd_selection` = ' ', `pd_definition` = ' ' WHERE `pd_selection_id` = '$pd_selection_id' ") or die(mysql_error());
}
}
If I echo the "entry" variable, this is what I receive:
[selection_for_1=Strongly Agree][definition_for_1=I strongly agree with this statement.][selection_for_2=Agree][definition_for_2=I agree with this statement.]
How do I pull the selection and the definition out of the array for each rating?
How is that used to update the database?
Am I even on the right track...LOL!?
Thank you very much for any help you can provide.
For security purpose you should keep a list of keys you would accept to prevent the user from modifying it, this will keep people from adding non valid data to your form as well as keeping out fields you may not want.
Create an array for selection another for definition, and use it to store the key/value while checking for valid fields:
$accept = array('selection_for_1', 'definition_for_1',
'selection_for_2', 'definition_for_2');
$selection = array();
$definition = array();
foreach ($_POST as $key => $value)
{
// if not valid go to next field/value
if(!in_array($key, $accept))
continue;
// if start with selection save to $selection array
// otherwise to definition array
if (strpos($key, 'selection') !== false)
{
$selection[] = mysql_real_escape_string($value);
}
else
{
$definition[] = mysql_real_escape_string($value);
}
}
// count one of the array to select the paired fields
// and insert or update into database
$total = count($definition);
for ($i=0; $i < $total; $i++)
{
// Update query for the paired selection and definition
$query = mysql_query("UPDATE pd_selections
SET pd_selection = '{$selection[$i]}',
pd_definition = '{$definition[$i]}'
WHERE pd_selection_id = '{$pd_selection_id}'")
or echo("Could not insert or update selection '{$selection[$i]}', definition '{$definition[$i]}', failed with error:", mysql_error());
}
Live DEMO.

$_POST as $key => $value using checkboxes

I am having trouble getting a form to update the information passed from a check box. I was given this code.
$one = isset($_POST['one']) ? 'on' : 'off';
This works great as long as I call each check box separately. My problem is I have approximately 200 checkboxes in total.
Here is the code I am using to UPDATE with. Can anyone help me to figure out where to insert the code I was given into my present code? I've tried all sorts of variations.
if($_POST['submit']){
if(!empty($applicant_id)){
$sql = "UPDATE play SET ";
foreach($_POST as $key => $value){
if(($key != 'submit') && ($key != 'applicant_id')){
$sql .= $key. " = '$value',";
}
}
$sql = substr($sql, 0, -1);
$sql .= " WHERE ".$applicant_id." = $applicant_id";
$result = mysql_query($sql,$db) or die(mysql_error(). "<br />SQL: $sql");
}
}
The solution is to start with your known list of possible checkboxes in an array() or similar. Can I assume you generate the form with such a list? If not, you probably should. Then you can use a loop over the same data to check for the existence of each checkbox.
Some other hints:
isset($array[$key]) is not recommended. Although it will be reliable most of the time, it will fail if $array[$key] is null. The correct call is array_key_exists($key, $array).
When assembling string fragments for SQL, like you're doing, it is more elegant to do the following:
$sqlvalues = array();
foreach( $options as $field ) {
if( array_key_exists('checkbox_'.$field, $_POST) )
$sqlvalues[] = $field.' = \'on\'';
else
$sqlvalues[] = $field.' = \'off\'';
}
mysql_query('UPDATE '.$table.' SET '.implode(', ', $sqlvalues).' WHERE applicant_id = '.$applicant_id);
You may be running to HTML checkbox behavior: Checkboxes are only sent to the server if they are on; if they are off, no name/value pair is sent. You are going to have trouble turning off values with the above code.
So you need to run through your known list of values and check for them in the $_POST parameters.
You should use an array name and it will be an array in PHP.
As ndp said, if a checkbox is unchecked, its value will not be transmitted. So you need to use a hidden input field with the same name before the checkbox input field, with the "off" value.
<label for="one">One</label>
<input type="hidden" name="checkboxes[one]" value="off"/>
<input type="checkbox" name="checkboxes[one]" id="one" value="on"/>
Remember checked="checked" if it should be default to on.
You can now loop the checkboxes with POST or GET
foreach ($_POST['checkboxes'] as $key => $value) {
//something
}
if($_POST['submit']){
if(!empty($applicant_id)){
$sql = "UPDATE play SET ";
foreach($_POST as $key => $value){
if(($key != 'submit') && ($key != 'applicant_id')){
$sql .= $key . " = '" . ($value ? 'on' : 'off') . "',";
}
}
$sql = substr($sql, 0, -1);
$sql .= " WHERE ".$applicant_id." = $applicant_id";
$result = mysql_query($sql,$db) or die(mysql_error(). "<br />SQL: $sql");
}
}
The above assumes that all your inputs are checkboxes. If they aren't, you'll need to work out a convention to distinguish them.
Incidentally, your currently running UPDATE code is vulnerable to SQL injection because you aren't sanitizing your inputs with mysql_real_escape_string(). Cheers.
delete everything above :-)
name all you checkboxes like
and in foreach work with $_POST['out']
BUT! don't forget the golden rule: DOn't belive to the user. re-check every key=>value before writing to the datebase.

Categories