PDO Insert from Web Form - php

What is wrong with the way that I am attempting a PDO insert using PHP and MySQL?
The MySQL database uses the same names as the ($_POST) variable.
<?php
if (!empty($_POST)) {
//Declare Database Variables Here
$dblist = ($_POST);
$keys = array_keys($data);
$dbcols = join(', ', array_values($keys));
$data = join(', ',array_values($dblist));
$dbtype = "mysql";
$dbhost = '127.0.0.1';
$dbname = 'bpstalent';
$dbuser = 'root';
$psword = 'root';
$portno = 3306;
// if table_name is submitted, display dynamic table with another form request for table name
$pdo = new PDO('mysql:host=' . $dbhost . ';port=' . $portno . 'dbname=' . $dbname . ';' . $dbuser . ';' . $psword . ';' );
echo "form submitted";
$sql = "INSERT INTO 'applicants'($dbcols) VALUES ($data)";
$stmt = $pdo->prepare($sql);
$stmt->execute();
}
else {
?>
html form here
<?
;}
?>

Also, I think you're an easy target to SQL injection. I would change
$sql = "INSERT INTO 'applicants'($dbcols) VALUES ($data)";
and replace values of $dbcols with hard coded list of columns (they can come from an array as well, just not one sent by user)
For the $data I would replace that with params what are handled by bindValue(). You can accomplish that by replacing "," with ",:" to convert names to para place holders. If echoed Your final query would look something like this:
$sql = "INSERT INTO applicants (col1, col2, col3) VALUES (:col1, :col2, :col3)";
See this example in PHP docs, it will be worth your time to secure this form:
http://www.php.net/manual/en/pdostatement.bindvalue.php
Below is a reworked sample of your script, untested, but should give you an idea of how to make things safer:
<?php
if ($_POST) {
//HARDCODE COLUMNS, DO NOT RELY ON USER INPUT, BAD THINGS WILL HAPPEN IF YOU DO
$keys = array("col1", "col2", "col3");
$dbcols = '`'.join('`, `', $keys).'`';
$placeholders = ':'.join(', :', $keys);
//RUN THROUGH POST DATA LOOKING FOR YOUR KEYS, ONLY PASS TO DATABASE DATA YOU ARE EXPECTING TO SEE
$data = array();
foreach ($keys as $k)
{
$data[$k] = $_POST[$k];
}
//CONSIDER REPLACING THIS WITH require_once() FILE
$dbtype = "mysql";
$dbhost = '127.0.0.1';
$dbname = 'bpstalent';
$dbuser = 'root';
$psword = 'root';
$portno = 3306;
$pdo = new PDO("$dbtype:host=$dbhost;port=$portno;dbname=$dbname", $dbuser, $psword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO applicants ($dbcols) VALUES ($placeholders)";
$stmt = $pdo->prepare($sql);
$stmt->execute($data);
}

Related

How do I get the value of the form into a MySQL table? [duplicate]

This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 2 years ago.
All I want is to get the var1 from the input into my SQL table. It always creates a new ID, so this is working, but it leaves an empty field in row Email. I never worked with SQL before and couldn't find something similar here. I thought the problem could also be in the settings of the table, but couldn't find anything wrong there.
<input name="var1" id="contact-email2" class="contact-input abo-email" type="text" placeholder="Email *" required="required"/>
<form class="newsletter-form" action="newsletter.php" method="POST">
<button class="contact-submit" id="abo-button" type="submit" value="Abonnieren">Absenden
</button>
</form>
<?php
$user = "user";
$password = "password";
$host = "localhost:0000";
$dbase = "base";
$table = "table";
// Connection to DBase
$con = new mysqli($host, $user, $password, $dbase) or die("Can't connect");
$var1 = $_POST['var1'];
$sql = "INSERT INTO table (id, Email) VALUES ('?', '_POST[var1]')";
$result = mysqli_query($con, $sql) or die("Not working");
echo 'You are in!' . '<br>';
mysqli_close($con);
is the id a unique id? that's auto-incremented??
if so you should do something like this
<?php
$user = "user";
$password = "password";
$host = "localhost:0000";
$dbase = "base";
$table = "table";
$mysqli = new mysqli($host,$user,$password,$dbase);
$email = $_POST['var1'];
// you might want to make sure the string is safe this is escaping any special characters
$statment = $mysqli->prepare("INSERT INTO table (Email) VALUES (?)");
$statment->bind_param("s", $email);
if(isset($_POST['var1'])) {
$statment->execute();
}
$mysqli->close();
$statment->close();
Simple answer
There are a few things wrong here; but the simple answer is that:
$sql = "INSERT INTO table (id, Email) VALUES ('?', '_POST[var1]')";
...should be:
$sql = "INSERT INTO {$table} (id, Email) VALUES ('?', '{$var1}')";
...OR assuming id is set to auto-increment etc. etc.
$sql = "INSERT INTO {$table} (Email) VALUES ('{$var1}')";
More involved answer
You should really take the time to use prepared statements with SQL that has user inputs. At the very least you should escape the strings yourself before using them in a query.
mysqli
$user = "user";
$password = "password";
$host = "localhost:0000";
$dbase = "base";
$table = "table";
$mysqli = new mysqli($host, $user, $password, $dbase); // Make connection to DB
if($mysqli->connect_error) {
die("Error: Could not connect to database.");
}
$email = $_POST["var1"]; // User input from form
$sql = "INSERT INTO {$table} (Email) VALUES(?)"; // SQL query using ? as a place holder for our value
$query = $mysqli->prepare($sql); // Prepare the statement
$query->bind_param("s", $email); // Bind $email {s = data type string} to the ? in the SQL
$query->execute(); // Execute the query
PDO
$user = "user";
$password = "password";
$host = "localhost:0000";
$dbase = "base";
$table = "table";
try {
$pdo = new pdo( "mysql:host={$host};dbname={$dbase}", $user, $password); // Make connection to DB
}
catch(PDOexception $e){
die("Error: Could not connect to database.");
}
$email = $_POST["var1"]; // User input from form
$sql = "INSERT INTO {$table} (Email) VALUES(?)"; // SQL query using ? as a place holder for our value
$query = $pdo->prepare($sql); // Prepare the statement
$query->execute([$email]); // Execute the query binding `(array)0=>$email` to place holder in SQL

How to insert rows of a table from one database to another (with two PDO)

I would like to insert all the data of a table presented on the database of our network
on a remote database (present on a remote server)
(this action will automate every 30 minutes)
The problem is that I do not see how to retrieve all the data from the table_local and insert them directly into the table_remote.
Indeed, to connect to these two databases, I use PDO
<?php
// LOCAL
$user = 'user1';
$password = 'password1';
$dns = 'completeDNS1';
$bdd = new PDO($dns, $user, $password);
$request = $bdd->prepare("SELECT * FROM table_local");
$request ->execute();
// REMOTE
$user = 'user2';
$password = 'password2';
$dns = 'completeDNS2';
$bdd = new PDO($dns, $user, $password);
// How to insert the previous data on the table_remote ?
?>
I would like to avoid, if possible, the foreach because the script will be launched very often and the table_local contains a lot of line
Is there a simple solution?
One method is using one tool like navicat or sequel pro to achieve.
Another method is using following codes:
$sql = "INSERT INTO table_name (column1, column2...) VALUES ";
foreach($res $key => $val) {
$sql .= "($val['column1'],$val['column2']...),";
}
$sql = rtrim($sql, ',');
...
<?php
// LOCAL
$user = 'user1';
$password = 'password1';
$dns = 'completeDNS1';
$bdd1 = new PDO("mysql:host=localhost;dbname=$dns", $user, $password);
$user = 'user2';
$password = 'password2';
$dns = 'completeDNS2';
$bdd2 = new PDO("mysql:host=localhost;dbname=$dns", $user, $password);
$request = $bdd1->prepare("SELECT * FROM table_local");
// REMOTE
while ($row = $request->fetch()) {
$sql = "INSERT INTO table_remote (name, surname, sex) VALUES (?,?,?)";
$stmt= $bdd2->prepare($sql);
$stmt->execute([$row['name'], $row['surname'], $row['sex']]);
}
?>
for reference check this link https://phpdelusions.net/pdo_examples/insert

Secure php and sql when selecting and inserting data

I have an app that takes data from MySQL database and also inserting data into it (the user is writing the data that is getting inserted) and honestly I am pretty new to php and don't know a lot about securing and sanitizing strings,
I want to make the php files more secure and I don't know what to look for in order of doing it, if someone can send a tutorial it will be great.
here is the select and insert codes
<?php
header('Content-Type: text/html; charset=utf-8');
$db = "*********";
$username = "*********";
$password = "*******";
$host = "************";
$sql = "select * from sample;";
$conn = mysqli_connect($host,$username,$password,$db);
$conn->set_charset('utf8');
$result = mysqli_query($conn,$sql);
$response = array();
while($row = mysqli_fetch_array($result))
{
array_push($response,array($row[0],$row[1],$row[2]));
}
$str = json_encode(array($response),JSON_UNESCAPED_UNICODE);
$str = clean($str);
echo $str;
mysqli_close($conn);
function clean($string) {
$string = str_replace(' ', ' ', $string);
$string = preg_replace('/[^a-zA-Z0-9,×-×–, : . -]/', '', $string);
return preg_replace('/-+/', '-', $string);
}
?>
and the insert:
<?php
$db = "*********";
$username = "*********";
$password = "*******";
$host = "************";
$conn = mysqli_connect($server_name,$mysql_username,$mysql_password,$db_name);
$name =$_POST["name"];
$publisher=$_POST["publisher"];
$date=$_POST["date"];
$sql_query = "insert into sample(name,publisher,date)
values('$name','$publisher','$date');";
if(mysqli_query($conn,$sql_query))
{
echo "data inserted";
}
else
{
echo "error";
}
?>
Use prepared statements any time possible:
$sql_query = "insert into sample(name,publisher,date) values(?,?,?);";
$stmt = mysqli_prepare($conn,$sql_query);
mysqli_stmt_bind_param( $stmt , "sss" , $name,$publisher,$date);
mysqli_stmt_execute($stmt);
And try to use the object style only, not the procedural of the mysqli extention.
You are mixing both here:
$conn = mysqli_connect($host,$username,$password,$db);//procedural style
$conn->set_charset('utf8');//oject style
You can use PDO. It's very simple to build safe SELECT and INSERT queries. Although, you must be careful on some commands such as ORDER BY.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=databasename;charset=utf8', 'username', 'password');
$statement = $pdo->prepare("SELECT * FROM users WHERE firstname = :firstname AND lastname = :lastname");
$statement->execute(array(':firstname' => 'Max', ':lastname' => 'Mustermann'));
if( $statement->rowCount() > 0 ) {
$row = $statement->fetch();
echo "Hello " . $row['firstname'];
}
?>
Mysqli can be used too, but please check out mysqli_real_escape_string.

Safe PDO mySQL SELECT statement with for loop

I was told to use PDO to safely retrieve data from a database. Now I'm wondering if this would be safe or work at all:
$dbtype = "sqlite";
$dbhost = "localhost";
$dbname = "test";
$dbuser = "root";
$dbpass = "admin";
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);
$firstName = htmlspecialchars($_POST["firstName"]);
foreach($conn->query('SELECT * FROM employeeTable WHERE firstName = ' . $firstName) as $row) {
echo $row['lastName'].' '.$row['email'];
}
Because to me it looks like it would still be possible to "inject" something into the query.
So my question is: Is that really safe and if not how exactly would I make it safe?
I think you'd better use the following to prepare, the process of preparing is to void the injection
$sql = 'SELECT * FROM employeeTable WHERE firstName = :firstName';
$sth = $conn->prepare($sql);
$sth -> bindParam(':firstName', $firstName);
$sth -> execute();
$result = $sth->fetchAll(PDO::FETCH_OBJ);
foreach ($result as $key => $value) {
echo $value->lastName, $value->email;
}
Just remember to don't directly concatenate post variables to your query, just use prepared statements. And after the execution of prepared statements, you need to fetch the results:
$select = $conn->prepare('SELECT * FROM employeeTable WHERE firstName = :firstName');
$select->execute(array(':firstName' => $_POST["firstName"));
while($row = $select->fetch(PDO::FETCH_ASSOC))
echo $row['lastName'].' '.$row['email'];
}
Here is a good read:
http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers

How do I insert into a form with over 100 fields

I've created a user form in which once the submit button is pressed I would like to send/insert the data to mysql database adding a new record. The form has over 100 input fields. How can I accomplish this. Here is my sample php code.
<html>
<head>
</head>
<body>
<?php
if (isset($_POST['submit'])){
//Variables for connecting to your database.
//These variable values come from your hosting account.
$hostname = "hostname";
$username = "username";
$password = "password";
$dbname = "dbname";
$mystuff = "tenant_lname","tenant_fname","tenant_mname","ssn","dl_number","dl_state","birthday","tenant_hphone","tenant_wphone","tenant_cphone","curr_street","curr__unit","curr_city","curr_state","curr_zip","how_long_from","how_long_to","last_rent_mnt","last_rent_amt","own_man_name","own_man_tel","curr_reason","pre_street","pre_unit","pre_city","pre_state","pre_zip","pre_from","pre_to","pre_last_rent","pre_amt","pre_owner","pre_owner_tel","pre_reason","sec_pre_street","sec_pre_unit","sec_pre_city","sec_pre_state","sec_pre_zip","sec_pre_from","sec_pre_to","sec_pre_last_paid_mnt","sec_pre_amt","sec_pre_owner","sec_pre_owner_tel","sec_pre_reason","curr_emp_name","curr_emp_add","curr_emp_phone","curr_emp_pos","curr_emp_bus_type","curr_emp_sup","curr_emp_from","curr_emp_to","curr_emp_salary","pre_emp_name","pre_emp_add","pre_emp_phone","pre_emp_pos","pre_emp_bus_type","pre_emp_sup_name","pre_emp_from","pre_emp_to","pre_emp_salary","move_date","addntl_occ_name","addntl_occ_age","addntl_occ_relation","addntl_ft","addntl_pt","addntl_occ1_name","addntl_occ1_age","addntl_occ1_relation","addntl_occ1_ft","addntl_occ1_pt","addntl_occ2_name","addntl_occ2_age","addnt2_occ1_relation","addntl_occ2_ft","addntl_occ2_pt","addntl_occ3_name","addntl_occ3_age","addntl_occ3_relation","addntl_occ3_ft","addntl_occ3_pt","credit_yes","credit_no","det_yes","det_no","evict_yes","evict_no","bnkry_yes","bnkry_no","fel_yes","fel_no","pet_yes","pet_no","pet_numb","pet_type","furn_yes","furn_no","ins_cov_yes","ins_cov_no","ints_yes","ints_no","ints_type","smoke_yes","smoke_no","occ_smoke_yes","occ_smoke_no","explain_smoke","bnk_name","bnk_add","checking","checking_bal","saving","saving_bal","bnk_name1","bnk_add1","checking1","checking_bal1","saving1","saving_bal1","other_income","credit_name","credit_add","credit_city","credit_acct","credit_bal","credit_payment","credit_name1","credit_add1","credit_city1","credit_acct1","credit_bal1","credit_payment1","credit_acct2_name","credit_add2","credit_city2","credit_acc2","credit_bal2","credit_payment2","credit_acc3_name","credit_acc3_add","credit_acc3_city","credit_acc3_number","credit_acc3_bal","credit_acc3_payment","emer_contact_name","emer_contact_add","emer_relation","emer_phone","reg_owner_yes","reg_owner_no","reg_who","vehicle_year","vehicle_make","vehicle_model","vehicle_color","vehicle_license","veh_state","vehicle2_year","vehicle2_make","vehicle2_model","vehicle2_color","vehicle2_license","veh2_state";
$con = mysql_connect("$hostname","$username","$password");
if (!$con){
die ("Can not connect:" . mysql_error());
}
mysql_select_db("dbname",$con);
$sql = "INSERT INTO dbname ($mystuff) VALUES ('$_POST[$mystuff]')";
mysql_query($sql,$con);
mysql_close($con);
}
?>
</body>
</html>
$mystuff should be an array.
You can generate your query and form with an loop.
Do validation if these is for productive use!
$_POST is also an array, so $_POST["field1", "field2", ...] ist an syntax error.
You can only access one key at once e.g. $_POST['field1'] . ',' . $_POST['field2']
You can join all values in an array by an char (e.g. ',') with implode()
rethink your Database schema!
untested:
<html>
`enter code here`<head>
`enter code here`</head>
<body>
<?php
>if (isset($_POST['submit'])){
//Variables for connecting to your database.
//These variable values come from your hosting account.
$hostname = "hostname";
$username = "username";
$password = "password";
$dbname = "dbname";
$mystuff = array( "tenant_lname","tenant_fname","tenant_mname","ssn","dl_number","dl_state","birthday","tenant_hphone","tenant_wphone","tenant_cphone","curr_street","curr__unit","curr_city","curr_state","curr_zip","how_long_from","how_long_to","last_rent_mnt","last_rent_amt","own_man_name","own_man_tel","curr_reason","pre_street","pre_unit","pre_city","pre_state","pre_zip","pre_from","pre_to","pre_last_rent","pre_amt","pre_owner","pre_owner_tel","pre_reason","sec_pre_street","sec_pre_unit","sec_pre_city","sec_pre_state","sec_pre_zip","sec_pre_from","sec_pre_to","sec_pre_last_paid_mnt","sec_pre_amt","sec_pre_owner","sec_pre_owner_tel","sec_pre_reason","curr_emp_name","curr_emp_add","curr_emp_phone","curr_emp_pos","curr_emp_bus_type","curr_emp_sup","curr_emp_from","curr_emp_to","curr_emp_salary","pre_emp_name","pre_emp_add","pre_emp_phone","pre_emp_pos","pre_emp_bus_type","pre_emp_sup_name","pre_emp_from","pre_emp_to","pre_emp_salary","move_date","addntl_occ_name","addntl_occ_age","addntl_occ_relation","addntl_ft","addntl_pt","addntl_occ1_name","addntl_occ1_age","addntl_occ1_relation","addntl_occ1_ft","addntl_occ1_pt","addntl_occ2_name","addntl_occ2_age","addnt2_occ1_relation","addntl_occ2_ft","addntl_occ2_pt","addntl_occ3_name","addntl_occ3_age","addntl_occ3_relation","addntl_occ3_ft","addntl_occ3_pt","credit_yes","credit_no","det_yes","det_no","evict_yes","evict_no","bnkry_yes","bnkry_no","fel_yes","fel_no","pet_yes","pet_no","pet_numb","pet_type","furn_yes","furn_no","ins_cov_yes","ins_cov_no","ints_yes","ints_no","ints_type","smoke_yes","smoke_no","occ_smoke_yes","occ_smoke_no","explain_smoke","bnk_name","bnk_add","checking","checking_bal","saving","saving_bal","bnk_name1","bnk_add1","checking1","checking_bal1","saving1","saving_bal1","other_income","credit_name","credit_add","credit_city","credit_acct","credit_bal","credit_payment","credit_name1","credit_add1","credit_city1","credit_acct1","credit_bal1","credit_payment1","credit_acct2_name","credit_add2","credit_city2","credit_acc2","credit_bal2","credit_payment2","credit_acc3_name","credit_acc3_add","credit_acc3_city","credit_acc3_number","credit_acc3_bal","credit_acc3_payment","emer_contact_name","emer_contact_add","emer_relation","emer_phone","reg_owner_yes","reg_owner_no","reg_who","vehicle_year","vehicle_make","vehicle_model","vehicle_color","vehicle_license","veh_state","vehicle2_year","vehicle2_make","vehicle2_model","vehicle2_color","vehicle2_license","veh2_state");
$sql_values=array();
foreach($mystuff as $fieldname) {
/* do validation! */
$sql_values[$fieldname] = "'" . mysql_real_excape_stiring($_POST[$fieldname]) . "'";
}
$con = mysql_connect("$hostname","$username","$password");
if (!$con){
die ("Can not connect:" . mysql_error());
}
mysql_select_db("dbname",$con);
$sql = "INSERT INTO dbname (".implode(',', $mystuff).") VALUES (" . implode(',', $sql_values) . ")";
mysql_query($sql,$con);
mysql_close($con);
}
foreach($mystuff as $fieldname) {
echo "...an input field...";
}
?>
</body>
Create inputs something like :
<input type="text" name="datas[firstname]"/>
<input type="text" name="datas[lastname]"/>
You can process the data using :
<?php
$datas = $_POST['datas'];
$columns = implode(",",array_keys($datas));
//add ' since mysql use ' for strings
$values = implode("','",$datas);
$sql = "INSERT INTO dbname (".$columns.") VALUES ('".$values."')";
Hope this help.

Categories