Inserting a variable with multiple values into a mysql database - php

I thought I would edit my question as by the comment it seems this is a very insecure way of doing what I am trying to acheive.
What I want to do is allow the user to import a .csv file but I want them to be able to set the fields they import.
Is there a way of doing this apart from the way I tried to demonstrate in my original question?
Thank you
Daniel
This problem I am having has been driving me mad for weeks now, everything I try that to me should work fails.
Basically I have a database with a bunch of fields in.
In one of my pages I have the following code
$result = mysql_query("SHOW FIELDS FROM my_database.products");
while ($row = mysql_fetch_array($result)) {
$field = $row['Field'];
if ($field == 'product_id' || $field == 'product_name' || $field == 'product_description' || $field == 'product_slug' || $field == 'product_layout') {
} else {
echo '<label class="label_small">'.$field.'</label>
<input type="text" name="'.$field.'" id="input_text_small" />';
}
}
This then echos a list of fields that have the label of the database fields and also includes the database field in the name of the text box.
I then post the results with the following code
$result = mysql_query("SHOW FIELDS FROM affilifeed_1000.products");
$i = 0;
while ($row = mysql_fetch_array($result)) {
$field = $row['Field'];
if ($field == 'product_name' || $field == 'product_description' || $field == 'product_slug' || $field == 'product_layout') {
} else {
$input_field = $field;
$output_field = mysql_real_escape_string($_POST[''.$field.'']);
}
if ($errorcount == 0) {
$insert = "INSERT INTO my_database.products ($input_field)
VALUES ('$output_field')";
$result_insert = mysql_query($insert) or die ("<br>Error in database<b> ".mysql_error()."</b><br>$result_insert");
}
}
if ($result_insert) {
echo '<div class="notification_success">Well done you have sucessfully created your product, you can view it by clicking here</div>';
} else {
echo '<div class="notification_fail">There was a problem creating your product, please try again later...</div>';
}
It posts sucessfully but the problem is that it creates a new "row" for every insert.
For example in row 1 it will post the first value and then the rest will be empty, in row 2 it will post the second value but the rest will be empty, row 3 the third value and so on...
I have tried many many many things to get this working and have researched the foreach loop which I haven't been familiar with before, binding the variable, imploding, exploding but none of them seem to do the trick.
I can kind of understand why it is doing it as it is wrapped in the while loop but if I put it outside of this it only inserts the last value.
Can anyone shed any light as to why this is happening?
If you need any more info please let me know.
Thank you
Daniel

You're treating each field you're displaying as its own record to be inserted. Since you're trying to create a SINGLE record with MULTIPLE fields, you need to build the query dynamically, e.g.
foreach ($_POST as $key => $value);
$fields[] = mysql_real_escape_string($key);
$values[] = "'" . msyql_real_escape_string($value) . "'";
} // build arrays of the form's field/value pairs
$field_str = implode(',', $fields); // turn those arrays into comma-separated strings
$values_str = implode(',', $values);
$sql = "INSERT INTO yourtable ($field_str) VALUES ($value_str);"
// insert those strings into the query
$result = mysql_query($sql) or die(mysql_error());
which will give you
INSERT INTO youtable (field1, field2, ...) VALUES ('value1', 'value2', ...)
Note that I'm using the mysql library here, but you should avoid it. It's deprecated and obsolete. Consider switching to PDO or mysqli before you build any more code that could be totally useless in short order.
On a security basis, you should not be passing the field values directly through the database. Consider the case where you might be doing a user permissions management system. You probably wouldn't want to expose a "is_superuser" field, but your form would allow anyone to give themselves superuser privileges by hacking up their html form and putting a new field saying is_superuser=yes.
This kind of code is downright dangerous, and you should not be using it in a production system, no matter how much sql injection protect you build into it.

Alright....I can't say that I know exactly whats going on but lets try this...
First off....
$result = mysql_query("SHOW FIELDS FROM my_database.products");
$hideArray = array("product_id","product_name","product_description", "product_slug","product_layout");
while ($row = mysql_fetch_array($result)) {
if (!in_array($row['Field'], $hideArray)){
echo '<label class="label_small">'.$field.'</label>
<input type="text" name="'.$field.'" id="input_text_small" />';
}
}
Now, why you would want to post this data makes not sense to me but I am going to ignore that.....whats really strange is you aren't even using the post data...maybe I'm not getting something....I would recommend using a db wrapper class...that way you can just through the post var into....ie. $db->insert($_POST) ....but if you ware doing it long way...
$fields = "";
$values = "";
$query = "INSERT INTO table ";
foreach ($_POST as $key => $data){
$values .= $data.",";
$fields .= $fields.",";
}
substr($values, 0, -1);
substr($fields, 0, -1);
$query .= "(".$fields.") VALUES (".$values.");";
This is untested....you can also look into http://php.net/manual/en/function.implode.php so you don't have to do the loop.
Basically you don't seem to understand what is going on in your script...if you echo the sql statements and you can a better idea of whats going....learn what is happening with your code and then try to understand what the correct approach is. Don't just copy and paste my code.

Related

Comparing Data Before and After Form Submission

I have a form page in which many of the elements are saved to different tables and different rows in my db. In order to minimize db calls I would like to compare the data before and after form submission, then I can write a function which will only update data that has been changed. To accomplish this I am saving the array that I used to build the form in a session file:
$this->session->set_tempdata('form_values_'.$item['id'],json_encode($item), 86400);
On form submission I retrieve this data and compare it to the $_POST:
$pre_post = json_decode($_SESSION['form_values_'.$_POST['id']], true);
Everything works great except in a few textareas where there is a "." in my test data. For some reason these fields come back as not equal even though I'm not changing the data.
It is definitely the period that is causing the problem, when I remove it it works fine. On the other hand there are other textareas that have periods that are not causing problems.
I thought it might be codeigniter's XSS filtering, but I removed that and it made no difference.
Originally i was using serialize to encode the array for storage, but I switched to json_encode and again it made no difference.
Here is the code I am using to compare the values:
$pre_post = json_decode($_SESSION['form_values_'.$_POST['id']], true);
$post = $this->security->xss_clean($_POST);
foreach ($post as $key => $value) {
if( !isset($pre_post[$key]) || trim($value)!=trim($pre_post[$key]) ){
$post_post[$key] = $value;
}
}
Any ideas?
Try this code may be it help you
$select = "SELECT * FROM ".$table_name." WHERE ".$field_name ." = '".$value."'";
$result_latest = mysql_query($select) or trigger_error(mysql_error());
while($row = mysql_fetch_array($result_latest,MYSQL_ASSOC))
{
$data_new = array_intersect_key($row,$data);
foreach($data_new as $k=>$v)
{
if(strcmp($row[$k],$data[$k]) != 0)
{
$string .= '`'.$k.'` = "'.$data[$k].'" ,';
}
}
}
$string = rtrim($string, ",");
if($string != NULL){
$update_sql = "UPDATE ".$table_name." SET ".$string." WHERE ".$field_name." = "."'".$value."'";
$query = $CI->db->query($update_sql);
}

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.

Passing multiple $_POST fields through MySQL search query

I have a search form with a possible 15 or so fields, however not all are required to carry out a search, for instance;
a user might search for a registered user in 'London' who works in 'Finance' but leave all other fields blank, such as $availability or $salary etc, so $_POST data may look something like:
$location = $_POST['location']; // Value - London
$sector = $_POST['sector']; // Value - Finance
$available = $_POST['available']; // Value - Any
$salary = $_POST['salary']; // Value - Any
Bearing in mind I may have another 12 or so 'Any' values from other fields, what is the best way to query the database (PHP/MySQL) to return results without looping through what would probably be dozens of queries.
To try and be a bit clearer, what i'd like is a query which would work something like (deliberate pseudo code):
SELECT * FROM table where location = 'location' AND if($availability !='Any') { available = '$available' } etc etc
Is something like this possible?
Or can I create a single string of all $_POST fields that !='Any' and then carry out a search on a row that contains all the words in the string (which I think would work in theory)?
I hope this makes sense to someone and you can point me in the right direction.
P.S. All $_POST is escaped and secured before interacting with database, just not included here :)
Try this:
$sql = "SELECT * FROM table where 1 ";
foreach ($_POST as $key => $post) {
if ($post != 'Any') {
$sql .= " AND $key = '$post' ";
}
}
// now you can run $sql against the database
Could you for argument sake collect all of the $_POST into a foreach($key=>$val) and then run the key through a switch or if statments that appends "AND x=x " to the statement?
Something like:
$sql = "SELECT * FROM table WHERE required='required'";
foreach($_POST as $key=>$val){
if(!empty($val)){ $sql .= " AND ".$key."='".$val"'"; }
}
Not sure if that works but in theory that is what i thought of first.
Thanks to those who offered answers, however I used the suggested answer found in the link above my question as it was clearer to me. Sample code pasted below FYI:
$tmp = "where ";
if($A and $A!="any" and $A!="not used")
$tmp .= "row1 = '".$A."'";
if($B and $B!="any" and $B!="not used")
$tmp .= "AND row2 = '".$B. "'";
if($C and $C!="any" and $C!="not used")
$tmp .= "AND row3 = '".$C."'";
$db_q = "Select * from table $tmp";
Thanks again, don't know where I'd be without SO.

Using $_POST in While PHP Question

I'm trying get some information via $_POST in PHP, basically at the moment i'm using this:
$item_name1 = $_POST['item_name1'];
$item_name2 = $_POST['item_name2'];
$item_name3 = $_POST['item_name3'];
$item_name4 = $_POST['item_name4'];
I want to insert each of the item names in a table field with mysql so i'm trying to experiment with the while php loop so i dont have lots of $item_name variables:
$number_of_items = $_POST['num_cart_items'];
$i=1;
while($i<=$number_of_items)
{
$test = $_POST['item_name'. $i''];
$i++;
}
The above code fails, its pretty tricky to explain but the code should find all the item_name $_POST and make it as a variable for mysql insertion.
The $_POST['num_cart_items'] is the total number of items.
The code is for a PayPal IPN listener for a shopping cart that is underway.
Help appreciated.
EDIT:
I have this further up the document which i just realised:
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
How can i insert $_POST['item_name1'], $_POST['item_name2'] as a variable for mysql insertion?
Your loop is effectively overriding the $test variable on each iteration:
$test = $_POST['item_name'. $i''];
If you want to put them in an array, change to $test[]. Also it contains the parse error as mentioned by brian_d.
It sounds a little scary to have a variable num_cart_items that is sent with the form. Are you setting it with JavaScript? The user can manipulate it. You should not rely on it. I belive what you need is to make the form feilds as:
<input type="text" name="item_name[]" />
Note the square brackets at the end of the name. This will create an array in the $_POST array: $_POST['item_name'] will contain the names of all the items.
Then, how is your DB structured? I guess you want to insert them in one query as:
INSERT INTO ORDERS VALUES (item_name_1, ...), (item_name_2, ...)
If so you can make a string out of the array:
$query = 'INSERT INTO ORDERS VALUES ';
foreach($_POST['item_name'] as $item_name){
$query .= '('.stripslashes($item_name). /*put other column values*/ '),';
}
$query = rtrim($query, ',');
Note that the use of addslashes is not enough to protect you from SQL injection.
$test = $_POST['item_name'. $i'']; is a syntax error.
remove the end '' so it becomes:
$test = $_POST['item_name'. $i];

$_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