I have a form which has multiple drop downs (16) speed[] and some other fields
The data from the dropdown boxes has to be inserted into a Mysql table
What I did is I took the count count($_POST["speed"]);and then loop through until the end of the speed array.
The problem is:
If Anyone of the dropdown is not selected it returns "-1", if used `($_POST["speed"][$i]!="-1")for that but it does not compare and goes into the IF loop
The Insert Query is not a valid not sure how to append the extra commas
$sql when printed
INSERT INTO mytablename (w_name,wtype,speed1,speed2, speed3, speed4, speed5, speed6, speed7, speed8, speed9, speed10, speed11, speed12, speed13, speed14, speed15, speed16, coach_id) VALUES ('name', '', ''-1''800''-1''-1''200''-1''-1''-1''-1''-1''-1''-1''-1''-1''-1''200'', '208')
My PHP code
$itemCount = count($_POST["speed"]);
$itemValues=0;
$query = "INSERT INTO mytablename (w_name,wtype,speed1,speed2, speed3, speed4, speed5, speed6, speed7, speed8, speed9, speed10, speed11, speed12, speed13, speed14, speed15, speed16, coach_id) VALUES ";
$bldSpltString="";
$queryValue = "";
for($i=0;$i<$itemCount;$i++) {
if(($_POST["speed"][$i]!="-1") || !empty($_POST["speed"][$i])) {
$bldSpltString .= "'" . $_POST["speed"][$i] ."'";
}
}
$queryValue .= "('" . $wkout . "', '" . $wtype . "', '" . $bldSpltString . "', '" .$_SESSION['id']."')";
$sql = $query.$queryValue;
echo $sql;
exit;
I would do something like this:
<?php
function dynamicInsert($table_name, $assoc_array){
$keys = array();
$values = array();
foreach($assoc_array as $key => $value){
$keys[] = $key;
$values[] = $value;
}
$query = "INSERT INTO `$table_name`(`".implode("`,`", $keys)."`) VALUES('".implode("','", $values)."')";
echo $query;
}
dynamicInsert("users", array(
"username" => "Test User",
"password" => "Password123"
));
?>
WARNING: This code is not secure, I would run a mysql_real_escape_string and any other necessary sanitation on the variables being sent to mysql. I would also steer clear of allowing this script to run on anything public facing as a dynamic insert could allow for huge security risks!
I have an SQL $query like this;
UPDATE `tags` SET `tags.name` = :name,
`tags.slug` = :slug,
`tags.date_published` = :date_published,
`tags.meta_title` = :meta_title,
`tags.meta_description` = :meta_description,
`tags.meta_keywords` = :meta_keywords
WHERE `tags.id` = :id
And my $values array;
Array
(
[:name] => iphone
[:slug] => iphone
[:date_published] => 2016-03-27
[:meta_title] => iphone Yazıları
[:meta_description] => iphone hakkında son gelişmeler ve faydalı bilgiler.
[:meta_keywords] => iphone yazıları, iphone hakkında bilgiler, iphone haberleri
[:id] => 24
)
I'm trying to update one row with PDO's prepare function;
$sth = $this->db->prepare($query);
$sth->execute($values);
echo "affected rows: ".$sth->rowCount(); // prints 0
return $sth->rowCount() ? true : false;
And I get no errors but rows are not affected after execute the query. Where is my mistake?
mysql tags table
edit:
I'm creating values array like this;
$params = array(
"id", "name", "slug", "date_published",
"meta_title", "meta_description", "meta_keywords");
$values = array();
foreach ($params as $key) {
#$values[$key] = $_POST[$key];
}
And this is how I create the query;
$query = "UPDATE `$table` SET";
$values = array();
/* Add field names and placeholders to query. */
foreach ($params as $key => $value) {
$query .= " `{$table}.{$key}` = :" . $key . ",";
$values[":" . $key] = $value;
}
/* Remove last comma. */
$query = substr($query, 0, -1);
/* Build where condition. */
if ($cond) {
$query .= " WHERE ";
foreach ($cond as $key => $value) {
$query .= " `{$table}.{$key}` = :" . $key . ",";
$values[":" . $key] = $value;
}
/* Remove last comma. */
$query = substr($query, 0, -1);
}
You're escaping the column names incorrectly. For example, the back ticks should not enclose the whole of tags.name, but rather the table and column names separately:
`tags`.`name`
Checking the output of PDO::errorInfo() confirms this (emulated prepares must be set to false in order to see this, however).
General notes:
You don't need to specify the colon prefix for the keys of the array being bound (likewise when explicitly binding columns via bindParam() or bindValue()).
You should avoid using back ticks in your PDO queries. They're a MySQL-specific feature, and PDO is not a SQL abstraction layer (thereby preventing one of the major benefits of PDO - portability).
Got a small problem regarding saving my form to the database and imploding. The issue is as following:
I have a form which has multiple fields, including checkboxes, which has an array of values. If I send the whole form to my php script it strips the checkbox value with the last one checked, so the issue is, I only get the last checked value in my database instead of all the checked values.
So I did a bit of debugging and I found the issue, it's in this line:
$values = "'" . implode("', '", $_POST) . "'";
This strips my data unfortunately.
EDIT:
This is my PHP script:
$hoeveelheidvalues = count($_POST);
$values = "'" . implode("', '", $_POST) . "'";
$queryvoorderesperform = "INSERT INTO `app_res_per_form` (";
for($i = 1; $i <= $hoeveelheidvalues; $i++)
{
if($i==$hoeveelheidvalues)
{
$queryvoorderesperform .= "vraag$i";
}
else{
$queryvoorderesperform .= "vraag$i, ";
}
}
$queryvoorderesperform .= ") VALUES ($values)";
EDIT 2:
If I use serialize I get a very weird string. This is the $queryvoorderespform:
INSERT INTO `app_res_per_form` (vraag1, vraag2, vraag3, vraag4, vraag5, vraag6, vraag7, vraag8, vraag9, vraag10, vraag11, vraag12)
VALUES (a:12:{s:16:"multipleradios-0";s:11:"Orientation";s:11:"textinput-0";s:0:"";s:20:"multiplecheckboxes-0";s:9:"Recycling";s:11:"textinput-1";s:0:"";s:10:"interestin";s:15:"Diverter Valves";s:12:"rotaryvalves";s:7:"AL, AXL";s:14:"divertervalves";s:3:"PTD";s:15:"othercomponents";s:3:"DUC";s:11:"textinput-3";s:0:"";s:16:"multipleradios-1";s:18:"Systems Integrator";s:16:"multipleradios-2";s:38:"Will buy product in long time (1 year)";s:15:"standcrewmember";s:13:"Aap";})
You can use serialize(), its a PHP function to convert an array or object into a string that can then be re-hydrated back into an array or object using unserialize();
$values = serialize($_POST);
or better still save the contents of $_POST as JSON using
$values = json_encode($_POST);
and re-hydrate into an array or object using
$var = json_decode($x);
These can be used on PHP Arrays or PHP Objects.
Ok now I see what you are actually trying to do so try this :-
$fields = '';
$values = '';
$count = 0;
foreach ( $_POST as $idx => $val ) {
// I assume you are skipping occurance 0 for a reason
if ( $count == 0 ) {
$count++;
continue;
}
$fields .= sprintf('vraag%d,', $count );
$values .= sprintf("'%s',", $val );
$count++;
}
//trim off trailing commas
rtrim($fields, ',');
rtrim($values, ',');
$sql = sprintf('INSERT INTO `app_res_per_form` (%s) VALUES (%s)',
$fields, $values);
}
Oh and I assume you are using the MYSQL_ extension! Someone is going to tell you not to and to switch to MYSQLI_ or PDO. So it may as well be me.
EDIT:
Thank you so much for your answers, you really amaze me with so much wisdom :)
I am trying to relay on TuteC's code a bit changed, but can't figure how to make it work properly:
$valor = $_POST['valor'];
$post_vars = array('iphone3g1', 'iphone3g2', 'nome', 'iphone41', 'postal', 'apelido');
foreach($post_vars as $var) {
$$var = "'" . mysql_real_escape_string($_POST[$var]). "', ";
}
$sql = "INSERT INTO clientes (iphone3g1, iphone3g2, nome, iphone41, postal, apelido, valor) VALUES ($$var '$valor')";
$query= mysql_query($sql);
I know there's a bit of cheating on the code, i would need to use substring so the $$var wouldn't output a "," at the end where i need the values, instead i tried to insert a variable that is a value ($valor = $_POST['valor'];)
What is going wrong?
And for the others who tried to help me, thank you very much, i am learning so much with you here at stackoverflow.
I have a form with several field values, when trying to write a php file that reads those values it came out a mostruosity:
$codigounico= md5(uniqid(rand()));
$modelo=$_POST['selectName'];
$serial=$_POST['serial'];
$nif=$_POST['nif'];
$iphone3g1=$_POST['iphone3g1'];
$iphone3g2=$_POST['iphone3g2'];
$iphone3g3=$_POST['iphone3g3'];
$iphone3g4=$_POST['iphone3g4'];
$iphone3gs1=$_POST['iphone3gs1'];
$iphone3gs2=$_POST['iphone3gs2'];
$iphone3gs3=$_POST['iphone3gs3'];
$iphone3gs4=$_POST['iphone3gs4'];
$iphone41=$_POST['iphone41'];
$iphone42=$_POST['iphone42'];
$iphone43=$_POST['iphone43'];
$iphone44=$_POST['iphone44'];
$total=$_POST['total'];
$valor=$_POST['valor'];
$nome=$_POST['nome'];
$apelido=$_POST['apelido'];
$postal=$_POST['postal'];
$morada=$_POST['morada'];
$notas=$_POST['notas'];
$sql="INSERT INTO clientes (postal, morada, nome, apelido, name, serial, iphone3g1, iphone3g2, iphone3g3, iphone3g4, total, valor, iphone3gs1, iphone3gs2, iphone3gs3, iphone3gs4, iphone41, iphone42, iphone43, iphone44, nif, codigounico, Notas)VALUES('$postal', '$morada', '$nome', '$apelido', '$modelo', '$serial', '$iphone3g1', '$iphone3g2', '$iphone3g3', '$iphone3g4', '$total', '$valor', '$iphone3gs1', '$iphone3gs2', '$iphone3gs3', '$iphone3gs4', '$iphone41', '$iphone42', '$iphone43', '$iphone44', '$nif', '$codigounico', '$notas')";
$result=mysql_query($sql);
This is a very dificult code to maintain,
can I make my life easier?
To restrict which POST variables you "import", you can do something like:
$post_vars = array('iphone3g1', 'iphone3g2', '...');
foreach($post_vars as $var) {
$$var = mysql_real_escape_string($_POST[$var]);
}
EDIT: Changed addslashes by mysql_real_escape_string (thanks #Czechnology).
The issue I see is repetition of the same names four times over. This is how I would reduce it to two occurrences (you could drop it to one with more finagling).
$sql = 'INSERT INTO clientes (postal, morada, nome, apelido, name, serial, iphone3g1, iphone3g2, iphone3g3, iphone3g4, total, valor, iphone3gs1, iphone3gs2, iphone3gs3, iphone3gs4, iphone41, iphone42, iphone43, iphone44, nif, codigounico, Notas) VALUES(:postal, :morada, :nome, :apelido, :modelo, :serial, :iphone3g1, :iphone3g2, :iphone3g3, :iphone3g4, :total, :valor, :iphone3gs1, :iphone3gs2, :iphone3gs3, :iphone3gs4, :iphone41, :iphone42, :iphone43, :iphone44, :nif, :codigounico, :notas)';
preg_match_all('/:(\w+)/', $sql, $inputKeys);
$tokens = $inputKeys[0];
$values = array_map($inputKeys[1], function($k){
return mysql_real_escape_string($_POST[$k]);
});
$sql = str_replace($tokens, $values, $sql);
$result = mysql_query($sql);
Depending on how you want to separate your logic, a reversed approach might be more useful, where you would specify the array of key names and iterate over that to generate the SQL string.
<?php
$inputKeys = array('postal', 'morada', 'nome', 'apelido', 'name', 'serial', 'iphone3g1', 'iphone3g2', 'iphone3g3', 'iphone3g4', 'total', 'valor', 'iphone3gs1', 'iphone3gs2', 'iphone3gs3', 'iphone3gs4', 'iphone41', 'iphone42', 'iphone43', 'iphone44', 'nif', 'codigounico', 'Notas');
$keyList = '(' . implode(',', $inputKeys) . ')';
$valueList = 'VALUES (';
foreach ($inputKeys as $k) {
$valueList .= mysql_real_escape_string($_POST[$k]);
$valueList .= ',';
}
$valueList = rtrim($valueList, ',');
$valueList .= ')';
$sql = 'INSERT INTO clientes '.$keyList.' '.$valueList;
$result = mysql_query($sql);
This approach drops the occurrences of the keys to one and will probably more naturally with your application.
TuteC had a good aim but failed in details.
It makes me wonder, why noone has a ready made solution, but had to devise it on-the-fly. Nobody faced the same problem before?
And why most people trying to solve only part of the problem, getting variables only.
The goal is not to get variables.
The goal is to get a query. So, get yourself a query.
//quite handy way to define an array, saves you from typing zillion quotes
$fields = explode(" ","postal morada nome apelido name serial iphone3g1 iphone3g2 iphone3g3 iphone3g4 total valor iphone3gs1 iphone3gs2 iphone3gs3 iphone3gs4 iphone41 iphone42 iphone43 iphone44 nif codigounico Notas");
$sql = "INSERT INTO clientes SET ";
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$sql.= "`$field`='".mysql_real_escape_string($_POST[$field])."', ";
}
}
$sql = substr($set, 0, -2);
This code will create you a query without boring repeating the same field name many times.
But that's still not all improvements you can make.
A really neat thing is called a function.
function dbSet($fields) {
$set = '';
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$set.="`$field`='".mysql_real_escape_string($_POST[$field])."', ";
}
}
return substr($set, 0, -2);
}
put this function into your code library being included into all your scripts (you have one, don't you?)
and then use it for both insert and update queries:
$_POST['codigounico'] = md5(uniqid(rand()));//a little hack to add custom field(s)
if ($action=="update") {
$id = intval($_POST['id']);
$sql = "UPDATE $table SET ".dbSet($fields)." WHERE id = $id";
}
if ($action=="insert") {
$sql = "INSERT $table SET ".dbSet($fields);
}
So, your code become extremely short and reliable and even reusable.
The only thing you have to change to handle another table is $fields array.
It seems your database is not well planned as it contains seemingly repetitive fields (iphone*). You have to normalize your database.
The same approach to use with prepared statements can be found in this my question: Insert/update helper function using PDO
You could use a rather ugly part of PHP called variable variables, but it is generally considered a poor coding practice. You could include your database escaping at the same time. The code would look something like:
foreach($_POST as $key => $value){
$$key = mysql_real_escape_string($value);
}
The variable variables manual section says they do not work with superglobals like $_PATH, but I think it may work in this case. I am not somewhere where I can test right now.
PHP: extract
Be careful though and make sure you clean the data before using it.
$set = array();
$keys = array('forename', 'surname', 'email');
foreach($keys as $val) {
$safe_value = mysqli_escape_string($db, $_POST[$val]);
array_push($set, "$val='$safe_value'");
}
$set_query = implode(',', $set);
Then make your MySQL query something like UPDATE table SET $set_query WHERE... or INSERT INTO table SET $set_query.
If you need to validate, trim, etc, do it before the above code like this:
$_POST["surname"] = trim($_POST["surname"];
Actually, you could make your life easier by making your code a bit more complicated - escape the input before inserting into the database!
$sql =
"INSERT INTO clientes SET
"postal = '" . mysql_real_escape_string($_POST['postal']) . "', ".
"morada = '" . mysql_real_escape_string($_POST['morada']) . "', ".
...
First, I recommend you to create a key-value array like this:
$newClient = array(
'codigounico' => md5(uniqid(rand())),
'postal' => $_POST['postal'],
'modelo' => $_POST['selectName'],
...
);
In this array key is the column name your MySQL table.
In the code you've provided not every field is copied right from POST array (some are calculated, and some keys of the POST aren't equal with the tables column names), so you should use a flexible method.
You should still specify all columns and values but only once so code is still maintainable and you won't have any security errors if someone sends you a broken POST. As for me it looks more like configuration than coding.
Then I recommend you to write a function similar to this:
function buildInsertQuery($tableName, $keyValue) {
$result = '';
if (!empty($keyValue)) {
$delimiter = ', ';
$columns = '';
$values = '';
foreach ($keyValue as $key => $value) {
$columns .= $key . $delimiter;
$values .= mysql_real_escape_string($value) . $delimiter;
}
$columns = substr($columns, 0, -length($delimiter));
$values = substr($values, 0, -length($delimiter));
$result = 'INSERT INTO `' . $tableName . '` (' . $columns . ') VALUES (' . $values . ')';
}
return $result;
}
And then you can simply build your query with just one function call:
$query = buildInsertQuery('clientes', $newClient);
I'm trying to do something like this so I don't have to type out all of my post entries. I can't seems to get this to work though.
edit: added some changes.
foreach($_POST as $key => $value)
{
$key = "'".mysql_real_escape_string($key)."'";
$value = "'".mysql_real_escape_string($value)."'";
$qstring = "UPDATE load_test SET ".$key."=".$value." WHERE Id = '".$_POST['id']."'";
mysql_query($qstring);
}
What you are trying to do here is incredibly, dangerously insecure.
// List the fields that may be updated here
$expectedFields = array('fielda', 'fieldb');
// Updated values to be stored here
$updates = array();
// Generate the update strings
foreach ($_POST as $key => $value) {
if (in_array($key, $expectedFields)) {
$updates[] = "`$key` = '".mysql_real_escape_string($key)."'";
}
}
// Do all updates at once
$qstring = "UPDATE load_test SET " . join(', ', $updates) . " WHERE Id = '" . mysql_real_escape_string($_POST['id']) . "'";
mysql_query($qstring);
This improves several things
All updates happen in one query, rather than one per field
The fields are validated (and sanitised, as they're only accepted if they're in the valid list)
The ID value is also sanitised
foreach($_POST as $k=>$v){
#$select.=" `".mysql_real_escape_string($k)."` = '".mysql_real_escape_string($v)."',";
}
$select = rtrim($select,',');
$select = "UPDATE load_test SET".$select." WHERE id=".$_POST['id'];
mysql_query($select) or die(mysql_error());;
try this is alot faster then the previous one you want need to do more then 1 query
and other then that i think it's safe enough to escape the key since trying updating a column that doesn't exist doesn't get you anywhere, and trying to make an injection escaping will protect you from that, you should though make sure the id is numeric