PHP: mysqli INSERT INTO statement is not working [duplicate] - php

This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 3 years ago.
My php code for registration does not insert values to the database. I tried different ways but it is still not working. Here is the code:
Database connection:
<?php $link=mysqli_connect("localhost", "root", "");
mysqli_select_db($link, "dataadventurers");
?>
My registration form PHP code:
<?php
include "connection.php"; ?>
<?php
if(isset($_POST['submit1'])){
$firstname = $_POST['first_name'];
$lastname = $_POST['last_name'];
$middle = $_POST['middle_initial'];
$idnum = $_POST['id_number'];
$email = $_POST['email_add'];
$pass = $_POST['password'];
$bday = $_POST['birthdate'];
$course = $_POST['course'];
$year = $_POST['year'];
mysqli_query($link, "insert into member_registration values('', '$firstname', '$lastname'
, '$middle', '$idnum', '$email', '$pass', '$bday', '$course', '$year')");
?>

Welcome to StackOverflow.
First of all, your code is vulnerable to SQL Injection. This is a major flaw but thankfully, one that's easily fixed. It is important that you do not leave this open to SQL Injection, even if this is something just for you to use. It'll keep your data safe in the event that someone else manages to access it and also gets you in to good habits.
Secondly, your code isn't working because you haven't specified what columns you want to insert into.
Using your example as a basis, here's a working version.
DO NOT USE THIS, IT IS VULNERABLE CODE
<?php
$link=mysqli_connect("localhost", "root", "");
mysqli_select_db($link, "dataadventurers");
?>
<?php
include "connection.php";
?>
<?php
if(isset($_POST['submit1'])){
$firstname = $_POST['first_name'];
$lastname = $_POST['last_name'];
$middle = $_POST['middle_initial'];
$idnum = $_POST['id_number'];
$email = $_POST['email_add'];
$pass = $_POST['password'];
$bday = $_POST['birthdate'];
$course = $_POST['course'];
$year = $_POST['year'];
//If someone passes 2019'); drop table member_registration; -- for example as the year parameter, MySQL interprets the query string as two separate queries. One to insert a record and the second to drop the table and will execute both
mysqli_query($link, "insert into member_registration (firstname, lastname, middle, idnum, email, pass, bday, course, year) values( '$firstname', '$lastname', '$middle', '$idnum', '$email', '$pass', '$bday', '$course', '$year')");;
}
?>
A MORE SECURE VARIANT
I have a couple of SQL convenience functions based on PDO I use on a regular basis.
They pick up their credentials from an ini file stored outside of the publicly accessible folder structure.
The GetData procedure returns the results in the form of an associative array
UpdateData returns the amount of rows affected.
Ini file example
host=localhost
dbname=dataadventurers
username=user
password=pass
Convenience Functions
/*Put credential ini file path here*/
$credentialFile = "...";
function GetData($sql, $params = null, $paramtypes = null){
//Get database connection details
$credentialsArray = parse_ini_file($credentialFile);
//Create PDO Instance
$db = new PDO('mysql:host='.$credentialsArray['host'].';dbname='.$credentialsArray['dbname'].';charset=utf8mb4', $credentialsArray['username'], $credentialsArray['password'], array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
if(is_null($params)){ //If no parameters supplied, execute the query as is
$stmt = $db->query($sql);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
else{
if(count($params) <> count($paramtypes)){ //Check that the parameter count and type count are the same
throw new InvalidArgumentException;
}
$stmt = $db->prepare($sql); //Prepare the statement
for($i=0; $i<count($params); $i++){ //Bind the parameters
$stmt->bindValue($i+1, $params[$i], $paramtypes[$i]);
}
$stmt->execute(); //Execute query
$results = $stmt->fetchAll(PDO::FETCH_ASSOC); //Return the results as an associative array
}
return $results;
}
function UpdateData($sql, $params){
//Get database connection details
$credentialsArray = parse_ini_file($credentialFile);
//Create PDO Instance
$db = new PDO('mysql:host='.$credentialsArray['host'].';dbname='.$credentialsArray['dbname'].';charset=utf8mb4', $credentialsArray['username'], $credentialsArray['password'], array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
try{
$stmt = $db->prepare($sql); //Prepare the statement
is_null($params){ //If there aren't any parameters to bind...
$stmt->execute(); //...execute statement as is
}
else{
$stmt->execute($params); //otherwise execute with the supplied parameters
}
$results = $stmt->rowCount(); //Return the rowcount
return $results;
}
catch(PDOException $ex){ //Catch any PDO Exceptions
return $ex->getMessage(); //Return the exception message
}
}
Usage
The usage is simple. When selecting data, pass a SQL string, an array containing any parameters and an array containing the parameter types. These arrays must be of the same length.
When updating/inserting/deleting data, pass a SQL string and an array containing the parameters. There is no parameter type requirement for UpdateData.
//GetData with no parameters
$results = GetData('select * from member_registration', [], []);
//GetData with one parameter of type String.
$results2 = GetData('select * from member_registration where firstname = ?', ['David'], [PDO::PARAM_STR]);
//Your insert example
$parameters = [
$firstname,
$lastname,
$middle,
$idnum,
$email,
$pass,
$bday,
$course,
$year
];
$rowsAffected = UpdateData('insert into member_registration (firstname, lastname, middle, idnum, email, pass, bday, course, year) values(?, ?, ?, ?, ?, ?, ?, ?, ?)', $parameters);
Final Thoughts
You'll need to substitute the column names for the fields you have in your database. If any are auto-generated, such as an auto-incrementing ID field, omit that field so it works correctly.
One of your parameters is called $pass. If you're storing passwords in a database, ALWAYS store them in an encrypted form, preferably using bCrypt. This StackOverflow answer explains why/how.

Related

PHP Scripting: How to return the value of the ID field (primary key auto-increment 1) of the SQL record being written to

I'm creating a multi-page web survey form, and I have a PHP script process.php that takes my responses on www.buythosecars.com and places them in a mySQL table and redirects the user to www.buythosecars.com/survey_two.html.
I want to pass the ID value from the users_data table record where the responses are being stored, to survey_two so that the results in survey_two will get posted to the same record in user_data as the results from the first page.
The idea here being that survey_respondants don't need to login or otherwise identify themselves to answer the survey.
I think $_GET might be the way; but I'm new to PHP....
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {//Check it is coming from a form
//mysql credentials
$mysql_host = "buythosecarscom.fatcowmysql.com";
$mysql_username = "[redacted]";
$mysql_password = "[redacted]";
$mysql_database = "buythatcar";
//header("Location: survey_two.html");
$u_q1 = filter_var($_POST["question_1"], FILTER_SANITIZE_STRING); //set PHP variables like this so we can use them anywhere in code below
$u_q2 = filter_var($_POST["question_2"], FILTER_SANITIZE_STRING);
$u_q3 = filter_var($_POST["question_3"], FILTER_SANITIZE_STRING);
$u_q4 = filter_var($_POST["question_4"], FILTER_SANITIZE_STRING);
$u_q4b = filter_var($_POST["question_4b"], FILTER_SANITIZE_STRING);
$u_q5 = filter_var($_POST["question_5"], FILTER_SANITIZE_STRING);
$u_q6 = filter_var($_POST["question_6"], FILTER_SANITIZE_STRING);
$u_q7 = filter_var($_POST["question_7"], FILTER_SANITIZE_STRING);
$u_q8 = filter_var($_POST["question_8"], FILTER_SANITIZE_STRING);
$u_q9 = filter_var($_POST["question_9"], FILTER_SANITIZE_STRING);
$u_q10 = filter_var($_POST["question_10"], FILTER_SANITIZE_STRING);
//Open a new connection to the MySQL server
$mysqli = new mysqli($mysql_host, $mysql_username, $mysql_password, $mysql_database);
//Output any connection error
if ($mysqli->connect_error) {
die('Error : ('. $mysqli->connect_errno .') '. $mysqli->connect_error);
}
$statement = $mysqli->prepare("INSERT INTO users_data (question_1, question_2, question_3, question_4, question_4b, question_5, question_6, question_7, question_8, question_9, question_10) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); //prepare sql insert query
//bind parameters for markers, where (s = string, i = integer, d = double, b = blob)
$statement->bind_param('sssssssssss', $u_q1, $u_q2, $u_q3, $u_q4, $u_q4b, $u_q5, $u_q6, $u_q7, $u_q8, $u_q9, $u_q10); //bind values and execute insert query
if($statement->execute()){
//Modify to print the ID of the record where the response to question 3 has
//been entered instead of the response to question 3
print "Hello " . $u_q3 . "!, your message has been saved!";
}else{
print $mysqli->error; //show mysql error if any
}
}
?>
When you're saving that value, you're automatically redirecting the user to the second page. At this point, you could simply get the most recently inserted value:
$mysqli->insert_id
It's highly unlikely this won't be your target, though be aware that this could be an issue with precise timing and lots of users, if another user is entering their information at the exact same time.
To prevent this, I'd recommend simply retrieving the information on the second page based on a unique piece of information that's passed across in the first page. Considering you're working with cars, a licence plate number or VIN would be a great example of information that you could save that would be unique.
Then on the next page you can retrieve the target with something like:
$targetVIN = 1; // Logic to target your user based on unique ID
$query = "SELECT * FROM `cars` WHERE `vin` = " . $targetVIN;
$result = $mysqli->query($query);
while ($car = $result->fetch_object()) {
// Access properties via $car->vin, etc.
}

Can only add two values in prepared statement PHP

I'm very new to PHP and trying to create basic webservice.
Here is the code
$type_general = $_GET["type_general"];
$name = $_GET["name"];
$firstname = $_GET["firstname"];
$institution = $_GET["institution"];
$institution_name = $_GET["institution_name"];
$street_nr = $_GET["street_nr"];
$city_postal = $_GET["city_postal"];
$email = $_GET["email"];
$telephone = $_GET["telephone"];
$name_firstname_pneumoloog = $_GET["name_firstname_pneumoloog"];
$riziv_pneumoloog = $_GET["riziv_pneumoloog"];
$riziv = $_GET["riziv"];
$type_specialist = $_GET["type_specialist"];
// Add tracking of redemption
// $stmt = $this->db->prepare("INSERT INTO Registration (id,type_general,name,firstname,institution,institution_name,street_nr,city_postal,email,telephone,name_firstname_pneumoloog,riziv_pneumoloog,type_specialist,riziv) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
// $stmt->bind_param("is",NULL, $type_general, $name,$firstname,$institution,$institution_name,$street_nr,$city_postal,$email,$telephone,$name_firstname_pneumoloog,$riziv_pneumoloog,$type_specialist,$riziv);
$stmt = $this->db->prepare("INSERT INTO Registration (type_general,name) VALUES (?,?)");
$stmt->bind_param("is",$type_general,$name);
$stmt->execute();
$stmt->close();
$this->db->commit();
I have the following problems:
For the parameter type_general it always put 0 in my DB
When I try to add all the parameters it doesn't insert anything in my DB
Can anybody please help me with this?
Thanks in advance !
As your code looks like mysqli, you need the first parameter of bind_param() to specify the types of the variables.
So:
$stmt = $this->db->prepare("INSERT INTO Registration (type_general,name) VALUES (?,?)");
$stmt->bind_param("is",$type_general,$name);
assumes that the first parameter is an integer. If it is not - if it is a string - you would need:
$stmt = $this->db->prepare("INSERT INTO Registration (type_general,name) VALUES (?,?)");
$stmt->bind_param("ss",$type_general,$name);
And to insert all values:
$stmt = $this->db->prepare("INSERT INTO Registration (type_general,name,firstname,institution,institution_name,street_nr,city_postal,email,telephone,name_firstname_pneumoloog,riziv_pneumoloog,type_specialist,riziv) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)");
$stmt->bind_param("sssssssssssss",$type_general,$name,$firstname,$institution,$institution_name,$street_nr,$city_postal,$email,$telephone,$name_firstname_pneumoloog,$riziv_pneumoloog,$type_specialist,$riziv);
assuming that all variables are supposed to be strings...
With $stmt->bind_param you only bind on alias to one parameter, which means that you need to call the function twice, e.g.
$stmt = $this->db->prepare("INSERT INTO Registration (type_general,name) VALUES (:t,:n)");
$stmt->bind_param(":t",$type_general);
$stmt->bind_param(":n",$name);

MySQLi insert, successful database connection but not successfully inserted [duplicate]

This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 2 years ago.
I'm attempting to insert some data into a table using mysqli functions.
My connection works fine using the following:
function connectDB(){
// configuration
$dbuser = "root";
$dbpass = "";
// Create connection
$con=mysqli_connect("localhost",$dbuser,$dbpass,"my_db");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
return false;
}else{
echo '<br />successfully connected<br />';
return $con;
}
}
But when I attempt to run my insert function I get nothing in the database.
function newUserInsertDB($name,$email,$password){
$con = connectDB();
// Prepare password
$password = hashEncrypt($password);
echo $password . "<br />";
// Perform queries
mysqli_query($con,"SELECT * FROM users");
mysqli_query($con,"INSERT INTO users (name,email,password,isActivated) VALUES ($name,$email,$password,0)");
// insert
mysqli_close($con);
}
I have been looking through the list of mysqli functions for the correct way to give errors but they all seem to be regarding the connection to the DB, not regarding success of an insert (and I can clearly see in my DB that it is not inserting.)
What would be the best way to debug? Which error handling shall I use for my insert?
I've tried using mysqli_sqlstate which gives a response of 42000 but I cannot see any syntax errors in my statement.
As mentioned in my comment, you would be better off using a prepared statement. For example...
$stmt = $con->prepare(
'INSERT INTO users (name, email, password, isActivated) VALUES (?, ?, ?, 0)');
$stmt->bind_param('sss', $name, $email, $password);
$stmt->execute();
Using this, you don't have to worry about escaping values or providing quotes for string types.
All in all, prepared statements are much easier and much safer than attempting to interpolate values into an SQL string.
I'd also advise you to pass the $con variable into your function instead of creating it within. For example...
function newUserInsertDB(mysqli $con, $name, $email, $password) {
// Prepare password
$password = hashEncrypt($password);
// functions that "echo" can cause unwanted side effects
//echo $password . "<br />";
// Perform queries
$stmt = $con->prepare(
'INSERT INTO users (name, email, password, isActivated) VALUES (?, ?, ?, 0)');
$stmt->bind_param('sss', $name, $email, $password);
return $stmt->execute(); // returns TRUE or FALSE based on the success of the query
}
The quotes are missing from the mysql statement from around the values. Also, you should escape the values before inserting them into the query. Do this way:
mysqli_query($con,"INSERT INTO users (name,email,password,isActivated) VALUES ('".
mysqli_real_escape_string($con,$name)."','".
mysqli_real_escape_string($con,$email)."','".
mysqli_real_escape_string($con,$password)."',0)");
Regards

MySQL query returning an error

This returns a MySQL error:
<?php
$name = $_POST['inputName2'];
$email = $_POST['inputEmail2'];
$instruments = $_POST['instruments'];
$city = $_POST['inputCity'];
$country = $_POST['inputCountry'];
$distance = $_POST['distance'];
// ^^ These all echo properly ^^
// CONNECT TO DB
$dbhost = "xxx";
$dbname = "xxx";
$dbuser = "xxx";
$dbpass = "xxx";
$con = mysqli_connect("$dbhost", "$dbuser", "$dbpass", "$dbname");
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$query = "INSERT INTO depfinder (name, email, instrument1, instrument2, instrument3, instrument4, instrument5, city, country, max_distance) VALUES ($name, $email, $instruments[0], $instruments[1], $instruments[2], $instruments[3], $instruments[4], $city, $country, $max_distance)";
$result = mysqli_query($con, $query) or die(mysqli_error($con)); // script fails here
if (!$result)
{
echo "There was a problem with the signup process. Please try again later.";
}
else
{
echo "Success";
}
}
?>
N.B. I'm not sure whether it's relevant, but the user may not choose five instruments so some $instrument[] array values may be empty.
Bonus question: is my script secure enough or is there more I could do?
You need quotes around the string values in the query:
$query = "INSERT INTO depfinder
(name, email, instrument1, instrument2, instrument3, instrument4, instrument5, city, country, max_distance)
VALUES ('$name', '$email', '$instruments[0]', '$instruments[1]', '$instruments[2]',
'$instruments[3]', '$instruments[4]',
'$city', '$country', $distance)";
To answer your bonus question, your script is not secure at all, it is susceptible to SQL injection, and will also get a syntax error if any of the values contain apostrophes. You should use a prepared query with parameters rather than string substitution. Or if you use substitution, you should use mysqli_real_escape_string to protect against injection and syntax errors.
It looks like the lack of single quotes around the variables in your query seems to have been the initial issue. So that can be considered a quick fix.
But I went ahead and refactored your code to streamline it a bit as well as provide some basic validation.
Additions of note include using a $post_array to roll through your $_POST values and do basic value checking with isset & !empty. Just a side note, but in your original script—and in this cleanup—you are setting a $distance string but then you are not actually using that in this code. Does it show up later? Realted but what is $max_distance? Could you have mixed up $distance with $max_distance? Fair typo, but just something I noticed.
Also, another option to get away from the single quotes is to use mysqli_stmt_bind_param which I have set here as mysqli_free_result & mysqli_close to neatly end the MySQL process.
// Set a '$_POST' array and roll through each value.
$post_array = array('inputName2', 'inputEmail2', 'instruments', 'inputCity', 'inputCountry', 'distance');
foreach ($post_array as $post_key => $post_value) {
$$post_value = isset($_POST[$post_value]) && !empty($_POST[$post_value]) ? $_POST[$post_value] : null;
}
// CONNECT TO DB
$dbhost = "xxx";
$dbname = "xxx";
$dbuser = "xxx";
$dbpass = "xxx";
// Set the connection or die returning an error.
$con = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname) or die(mysqli_connect_error());
// Set the query.
$query = "INSERT INTO depfinder (name, email, instrument1, instrument2, instrument3, instrument4, instrument5, city, country, max_distance)"
. " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
;
// Bind the params.
mysqli_stmt_bind_param($query, 'ssssssssss', $inputName2, $inputEmail2, $instruments[0], $instruments[1], $instruments[2], $instruments[3], $instruments[4], $city, $country, $max_distance);
// Run the query.
$result = mysqli_query($con, $query) or die(mysqli_error());
// Check if the result is returned & echo a message based on that.
if (!$result) {
echo "There was a problem with the signup process. Please try again later.";
}
else {
echo "Success";
}
// Free the result set.
mysqli_free_result($result);
// Close the connection.
mysqli_close($con);

PHP PDO Insert query with prepared statements

I am trying to run an sql query using PDO prepared statements
$sql = "INSERT INTO tickets (ticketnumber, status) VALUES (1234, Open) ";
$stmt = $connection->prepare($sql);
$stmt->execute();
But it is just not inserting. What have I done wrong?
Here is my connection:
$host = "localhost";
$db_name = "";
$username = "";
$password = "";
$connection = new PDO("mysql:host={$host};dbname={$db_name}", $username, $password);
Try this. It's much more secure.
Make sure you have included your connection file.
EDITED
$sql = "INSERT INTO `tickets` (ticketnumber, status) VALUES (:ticketnumber, :status)";
$stmt = $connection->prepare($sql);
$stmt->bindValue(':ticketnumber', 1234, PDO::PARAM_INT);
$stmt->bindValue(':status', 'Open', PDO::PARAM_STR);
$stmt->execute();
Also, the named parameters used above must NOT be enclosed in quotes. If you do so, it'll be treated as a literal string and not a named parameter.
You need to use quotes on strings before inserting them into a database.
Why use prepare if you're not preparing your data before sending it to the database?

Categories