Can only add two values in prepared statement PHP - 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);

Related

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

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.

Parameter error, SQLSTATE[HY093]: Invalid parameter number: parameter was not defined

So I'm getting SQLSTATE[HY093]: Invalid parameter number: parameter was not defined, when I try to submit my form. I have a reservations folder with a index.php file that has an include file as reservations.html.php which has the forms in html.
So my forms in the reservations.html.php when filled out and has a value in first name will then try to post all the values in the form into the reservations table I have created in mysql. Below are my code in the index.php
<?php
// Edit or Replace this try/catch statement to work with the current PHT configuration
include '../includes/db.inc.php';
// Modify the If statement so the try only runs if the First Name field has been submitted AND the honeypot field is empty ''
if (isset($_POST['myfname'])) {
$myFName = $_POST['myfname'];
$myTour = $_POST['tour'];
$myLName = $_POST['mylname'];
$myEmail = $_POST['myemail'];
// If the if statement is true, save each form field value as a variable. These variable values will be used in the thank you page.
// And run the try/catch to attempt to insert data in the database. Modify the INSERT statement to write all the form filed values (except the honeypot) to the database.
try
{
$sql = 'INSERT INTO reservations SET
tour = :tour,
fname = :fname,
lname = :lname,
email = :email';
$s = $pdo->prepare($sql);
$s->bindValue(':tour', $myTour);
$s->bindValue(':myfname', $myFName);
$s->bindValue(':mylname', $myLName);
$s->bindValue(':myemail', $myEmail);
$s->execute();
}
catch (PDOException $e)
{
$error = 'Error adding submitted joke: ' . $e->getMessage();
include '../includes/error.html.php';
exit();
}
// load the thank you page after the INSERT runs
include 'success.html.php';
// Add an else to load the initial page if the initial (line 19) if statement is false
} else {
include 'reservations.html.php'; //Modify this to include the initial file for this folder
}
The syntax for your insert statement is off, and appears to be hybrid between an insert and an update. Try this version:
$sql = "INSERT INTO reservations (tour, fname, lname, email) ";
$sql .= "VALUES (:tour, :fname, :lname, :email)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':tour', $myTour, PDO::PARAM_STR);
$stmt->bindParam(':fname', $myFName, PDO::PARAM_STR);
$stmt->bindParam(':lname', $myLName, PDO::PARAM_STR);
$stmt->bindParam(':email', $myEmail, PDO::PARAM_STR);
$stmt->execute();
$stmt->close();
To be clear here, a SQL insert statement takes the following things:
The INSERT INTO keywords, followed by a list of columns
Then a VALUES clause, followed by a tuple containing the values to be inserted
There is also an INSERT INTO ... SELECT, which uses a select statement to provide the values, but you are not using this form.

php type def doesn't match bind params

I have a table with 5 columns where the first column is a primary key and has a Auto_INCREMENT attribute. I am trying to insert a row into the table using the following code:
<?php
include "DBConstants.php";
$db = new DBConstants();
$connection = new mysqli($db->SERVER_NAME,$db->DB_USERNAME,$db->DB_PASSWORD,$db->DB_NAME);
$query = "INSERT INTO mailinglist (email, validationID, usRequest, isValidated) VALUES (?,?,?,?)";
$statement = $connection->prepare($query);
$email = $_GET["email"];
$validationID = openssl_random_pseudo_bytes ( 10, $crstrong);
$usRequest=false;
$isValidated = false;
$statement->bind_param($email,$validationID,$usRequest,$isValidated);
$statement->execute();
$statement->close();
$connection->close();
$array = array("result"=>true,"message"=>"You have successfully subscribed");
echo json_encode($array);
?>
But I am getting a warning like this:
Warning: mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables
And hence the table is not being updated. Where am I going wrong?
The first parameter of bind_param should be type of corresponding bind variables.
$statement->bind_param('sisi', $email, $validationID, $usRequest, $isValidated);
Note: Change the types in first param based on your data type.
Reference Link

PDO::exec() expects parameter 1 to be string, object given

This is the code that makes the error:
$sql = 'INSERT INTO pedidos (pagado, instalado) VALUES ("'.$_POST['email'].'", "'.$_POST['b'].'") WHERE email="'.$_POST['2'].'"';
$stm = $conn->prepare($sql);
$conn->exec($stm);
That's not the proper way to use prepare and execute. The reason this was created was so that you wouldn't need to put logic and data together and put yourself at risk of an SQL injection attack.
$sql = 'INSERT INTO pedidos (pagado, instalado) VALUES (:pagado, :instalado)';
$stm = $conn->prepare($sql);
$stm->bindParam(':pagado', $_POST['email']);
$stm->bindParam(':instalado', $_POST['b']);
$stm->execute();
It also doesn't make sense to put a WHERE in an INSERT query. You're inserting into your table, you're not getting data.
However, if you're updating data based on other data, then you should use an UPDATE query.
UPDATE pedidos SET pagado=?, instalado=? WHERE email=?
An example of this would be:
$sql = 'UPDATE pedidos SET pagado=:padago, instalado=:instalado WHERE email=:email';
$stm = $conn->prepare($sql);
$stm->bindParam(':pagado', $_POST['email']);
$stm->bindParam(':instalado', $_POST['b']);
$stm->bindParam(':email', $_POST['2']);
$stm->execute();
UPDATE - 2:
$sql = 'INSERT INTO pedidos SET pagado = ?, instalado = ? WHERE email = ?';
$stm = $conn->prepare($sql);
$stm->bindParam(1,$_POST['email']);
$stm->bindParam(2,$_POST['b'] );
$stm->bindParam(3,$_POST['2'] );
$stm->execute(); // here your code generate error
Reason: You put $stm in execute() , which makes an error.

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