This question already has answers here:
Reference — frequently asked questions about PDO
(3 answers)
Closed 9 years ago.
I'm trying to insert values to mysql database, but for some reason this is not working. I can get it to work with normal PHP but I have been told that PDO would be safer to use. This is the code I use, the values are posted to the php file, but not updated to mysql. What could be the reason for that?
<?php
include 'config.php';
// database connection
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);
// new data
$value1 = $_POST["value1"];
$value2 = $_POST["value2"];
$value3 = $_POST["value3"];
$value4 = $_POST["value4"];
// query
$sql = "INSERT INTO `database`.`table`
(`id`, `value1`, `value2`, `value3`, `value4`, `timeStamp`)
VALUES (NULL, ?, ?, ?, ?, CURRENT_TIMESTAMP)";
$q = $conn->prepare($sql);
$q->execute(array($value1, $value2, $value3, $value4));
?>
Change this line
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);
to this
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
and use try catch on
try
{
$q->execute(array($value1, $value2, $value3, $value4));
}
catch(Exception $e)
{
echo $e->getMessage();
//other code to handle exception for example logging, rollback transaction if exists etc.
}
When you make these changes then PDO Exceptions will be thrown and you will see what problem is. With PDO exception you can do more to handle error, for example if you use transactions then you can in catch block rollback it.
You can use error_reporting(E_ALL); and display_errors with ini_set().
You can also use PDO::errorInfo
From manual:
PDO::errorInfo — Fetch extended error information associated with the last operation on the database handle
To see examples check this link
Check these links:
how to set display errors
info about exceptions
pdo exception
Related
This question already has answers here:
How to prevent duplicate usernames when people register?
(4 answers)
Closed 12 months ago.
I want to take email addresses from users to add them to a mailing list. However, I want to prevent duplicate entries, so I am using the INSERT IGNORE approach. I am using the PHP script below, but constantly receive this error:
Fatal error: Uncaught Error: Call to a member function bind_param() on bool
I've reviewed a LOT of SO articles on this error but still can't get it to work. I have confirmed that the $email and $id variables do have values. I suspect the error must have something to do with the use of IGNORE, but I honestly don't know.
Here's my code:
$email = filter_input(INPUT_POST, 'email',FILTER_SANITIZE_EMAIL);
$id = filter_input(INPUT_POST, 'id',FILTER_VALIDATE_INT) ?: NULL;
$sqlQuery = 'INSERT IGRNORE INTO email(email, id) VALUES(:email,:id);';
$stmt = $dbc->prepare($sqlQuery);
$stmt->bind_param(':email',$email);
$stmt->bind_param(':id',$id);
$stmt->execute();
mysqli_close($dbc);
I've tried including only one variable for the insert but I get the error against both bind_param lines. I also got the error when I had this structured to have both variables in a single bind_param entry.
I'm open to other ways of avoiding duplicate emails in the database, so long as they can be done with a single PHP file.
You are mixing PDO and mysqli syntax. You need to pick one.
PDO
Open the connection, execute the statement without IGNORE, and then catch the exception to see why it failed. The code 1062 means that MySQL tried to insert a duplicate value.
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", 'user', 'pass', [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => false
]);
try {
$stmt = $pdo->prepare('INSERT INTO email(email, id) VALUES(:email,:id)');
$stmt->execute([
'email' => $email,
'id' => $id
]);
} catch (PDOException $e) {
if ($e->errorInfo[1] === 1062) {
// duplicate
} else {
// If not 1062 then rethrow
throw $e;
}
}
mysqli
Using mysqli it's a little bit more work, but the same logic. With mysqli you can't use named placeholders and you can't bind-in-execute. The bind_param() function is very peculiar so pay special attention to the syntax.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$mysqli->set_charset('utf8mb4'); // always set the charset
try {
$stmt = $mysqli->prepare('INSERT INTO email(email, id) VALUES(?, ?)');
$stmt->bind_param('ss', $email, $id);
$stmt->execute();
} catch (mysqli_sql_exception $e) {
if ($e->getCode() === 1062) {
// duplicate
} else {
// If not 1062 then rethrow
throw $e;
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
Below is a my code write up in which i am trying to insert data into two different tables with help of transactions but code is not executing. Trying very hard to find out issue but unable to resolve it.
I am getting this error: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''u_id_fk','device_type','ip_num','package','pkg_id_fk') VALUES('79','abc','128.1' at line 1[]
$cust_name = 'multi';
$u_name = 'multi2';
$cnic_num = '421';
$address = 'sadaddd';
$password = md5('423423');
$cellnum='43243';
$p_id_fk=(int)'3';
try {
// First of all, let's begin a transaction
$conn->beginTransaction();
// If we arrive here, it means that no exception was thrown
// i.e. no query has failed, and we can commit the transaction
// Forgot to close the VALUES bracket and couldn't find your $email
$users_stmt=$conn->prepare("INSERT INTO users (`cust_name`, `u_name`, `cnic`, `address`, `password`, `email`) VALUES (:cust_name, :u_name, :cnic, :address, :password, :email)");
// PDO::execute() can accept an array of parameter bound to your query so you may avoid selecting data type when using bindParam()
$users_stmt->execute(["cust_name"=>$cust_name, "u_name"=>$u_name, "cnic"=>$cnic_num, "address"=>$address, "password"=>$password, "email"=>$email]);
// Not sure if $db is a PDO object...
$connections_stmt=$conn->prepare("INSERT INTO connections('u_id_fk','device_type','ip_num','package','pkg_id_fk') VALUES(:u_id_fk,:device_type,:ip_num,:package,:pkg_id_fk)");
$connections_stmt->execute(["u_id_fk"=>$u_id,"device_type"=>$device_type,"ip_num"=>$ip_num,"package"=>$package,"pkg_id_fk"=>$p_id_fk]);
$conn->commit();
} catch (Exception $e)
{
// An exception has been thrown
// We must rollback the transaction
$conn->rollback();
echo $e;
}
Please help to resolve it! Thanks
It is very important to set PDO error mode to EXCEPTION during connection.
Avoid using simple hashing algorithms for password as it can be extracted using Rainbow Attack.
$cust_name = 'multi';
$u_name = 'multi2';
$cnic_num = '421';
$address = 'sadaddd';
$password = md5('423423');
$cellnum='43243';
$p_id_fk=(int)'3';
try {
// DB vars
$db_host="";
$db_name="";
$db_username="";
$db_password="";
// Create a new PDO connection and set error mode to EXCEPTION
$conn=new PDO("mysql:host=".$db_host.";dbname=".$db_name,$db_username,$db_password,array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$conn->beginTransaction();
// Forgot to close the VALUES bracket and couldn't find your $email
$users_stmt=$conn->prepare("INSERT INTO users (`cust_name`, `u_name`, `cnic`, `address`, `password`, `email`) VALUES (:cust_name, :u_name, :cnic, :address, :password, :email)");
// PDO::execute() can accept an array of parameter bound to your query so you may avoid selecting data type when using bindParam()
$users_stmt->execute(["cust_name"=>$cust_name, "u_name"=>$u_name, "cnic"=>$cnic_num, "address"=>$address, "password"=>$password, "email"=>$email]);
$connections_stmt=$conn->prepare("INSERT INTO connections(`u_id_fk`,`device_type`,`ip_num`,`package`,`pkg_id_fk`) VALUES(:u_id_fk, :device_type, :ip_num, :package, :pkg_id_fk)");
$connections_stmt->execute(["u_id_fk"=>$u_id, "device_type"=>$device_type, "ip_num"=>$ip_num, "package"=>$package, "pkg_id_fk"=>$p_id_fk]);
$conn->commit();
} catch (Exception $e){
$conn->rollback();
echo $e->getMessage();
}
The closing double quotation in your first statement is not correct, it must be at the end of it and also you missed the end bracket of prepare function
$stmt=$conn->prepare("INSERT INTO users (cust_name, u_name,cnic,address,password,email) VALUES (?, ?, ?, ?, ?, ?)");
Try to correct that typo.
This question already has answers here:
Why is password_verify returning false?
(2 answers)
Closed 3 years ago.
I have a PHP function to insert a new user into a MySQL database using PDO but for some reason the data doesnt end up inserting, it doesn't throw an error and i can insert data manualy just fine but cant seem to figure out the issue?
public function createNewUser($username, $password, $firstname, $lastname)
{
try
{
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$sqlQuery = "INSERT INTO users(u_username, u_password, u_firstname, u_lastname, u_datecreated) VALUES (?, ?, ?, ?, ?)";
$statement = $this->_dbHandle->prepare($sqlQuery)->execute([$username, $hashedPassword, $firstname, $lastname, date(SQL_DATE)]);
print "INSERTED USER";
}
catch (PDOException $e)
{
echo $e->getMessage();
die();
}
}
I didn't realise you had to enable error messages when using PDO, after adding the following line, it showed me that my password column in the db wasn't large enough to store the hashed password.
$this->_dbHandle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
What is the proper way to "encapsulate" the sql queries scripts and connection script with try/catch or if/else blocks? I want to have a config.php file that will contain the connection part:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
try {
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
?>
Now taken from w3schools, when they insert a value to the database, they simply re-write the entire connection part again:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', 'john#example.com')";
// use exec() because no results are returned
$conn->exec($sql);
echo "New record created successfully";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
but I want to properly separate the two. Also, if I use prepared statements, do I need to check if on each part? i.e the prepare, bindParam and execute? Or a single try/catch or if/else is enough:
// Prepare an insert statement
$sql = "INSERT INTO table(value) VALUES (:value)";
$stmt = $conn->prepare($sql);
// Bind variables to the prepared statement as parameters
$stmt->bindParam(':value', $value, PDO::PARAM_STR);
$stmt->execute(); //does each part here need an if/else?
You should only make the connection once. There's no need to close and reopen the connection between queries. I assume the reason the example at w3schools is written that way is so that it will be self-contained, executable as-is without relying on a connection established in another example.
If you have the code that defines your connection in one file like the first example you showed, you can include that file in other files that need a connection to execute queries, and $conn will be available there. For a simple project, that's all you really need.
As far as if/else or try/catch, since you have set the PDO::ATTR_ERRMODE attribute on your connection to PDO::ERRMODE_EXCEPTION, then wrapping bits of code where a query may fail in if/else probably won't be that useful, because an exception will be thrown if the query fails, so handling the exception in a catch block will work better. You can examine the exception to see exactly what went wrong, log the error, and show an appropriate error message to the user where applicable. Dumping every exception message to the screen as shown in the second example is generally not a good way to show appropriate error messages to users.
You should include the prepare, bind, and execute in the try block. execute() is not the only thing that can cause an exception. prepare() may throw an exception if you aren't using emulated prepared statements (depending on the setting of PDO::ATTR_EMULATE_PREPARES), and bind can also cause an exception, for example if you mess up a named placeholder.
if/else is more useful for checking the results of queries that executed successfully (e.g. did this select statement return any records). The level of detail of error handling you need determines how many if/else, try/catch blocks you need.
This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
PHP's white screen of death [duplicate]
Closed 5 years ago.
I am new to using PDO and I am getting an http 500 server error when the form is submitted.
The php page with the processing code is in the correct folder so I don't know why its throwing up a 500 error.
There is NO url rewrite going on neither .
Here is my code:
try {
$dbh = new PDO("mysql:host=$hostname;dbname=crm",$username,$password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // <== add this line
$stmt = $db->prepare("INSERT INTO testdrives (forename, surname,phone,email,add1,add2,add3,city,county,postcode,car,date) VALUES (:forename, :surname,:phone,:email,:add1,:add2,:add3,:city,:county,:postcode,:car,:date)");
$stmt->bindParam(':forename', $_POST['forename']);
$stmt->bindParam(':surname', $_POST['surname']);
$stmt->bindParam(':phone', $_POST['phone']);
$stmt->bindParam(':email', $_POST['email']);
$stmt->bindParam(':add1', $_POST['add1']);
$stmt->bindParam(':add2', $_POST['add2']);
$stmt->bindParam(':add3', $_POST['add3']);
$stmt->bindParam(':city', $_POST['city']);
$stmt->bindParam(':county', $_POST['county']);
$stmt->bindParam(':postcode', $_POST['postcode']);
$stmt->bindParam(':car', $_POST['car']);
$stmt->bindParam(':date', $_POST['date']);
$stmt->execute();
if ($dbh->query($sql)) {
echo "<script type= 'text/javascript'>alert('New Record Inserted Successfully');</script>";
}
else{
echo "<script type= 'text/javascript'>alert('Data not successfully Inserted.');</script>";
}
$dbh = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
Edit:
I missed the incorrect variable used for the connection being $dbh and $db in the prepare; my bad.
Original answer.
This line:
if ($dbh->query($sql)) {...}
is failing for two reasons:
Calling query() on what is already being prepared/executed.
Using a non-existant variable, $sql.
Get rid of that statement with the related brace and replace it with simply and replacing the $stmt->execute(); with:
if($stmt->execute()){
// success
} else{
// error
}
and using PDO's error handling (as you are doing now) and PHP's error reporting:
http://php.net/manual/en/pdo.error-handling.php
http://php.net/manual/en/function.error-reporting.php
Check your logs also.
Found the problem
The above code shows
$stmt = $db->prepare
Needed to be changed to
$stmt = $dbh->prepare
Thanks for help with the other issue
Quick question how to i insert into a table that has an auto increment column ?