pdo catch and output mysql errors [duplicate] - php

This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed last year.
I have an insert statement that is executed with PDO. Insert works great however if there is an error I would like it displayed to the user.
I have the below try-catch block.
try{
$insertuser = $db->prepare('INSERT INTO `she_she`.`Persons` (`idnumber`,`addedby`,`firstname`, `middlename`, `surname`, `fullname`, `gender`, `birthdate`, `homelanguage`, `department`, `employeetype`, `employeestatus`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)');
$insertuser->execute(array($idnumber,$user,$firstname, $middlename, $surname, $fullname, $gender, $birthdate, $language, $department, $employmenttype, $personstatus));
}
catch(PDOException $exception){
return $exception;
}
If the query fails, or let's say a duplicate IDNumber, I want this displayed to the user.
If I simply try to echo the variable $exception it does not work.
I want to return the MySQL error to the user.

By default PDO is not in a state that will display errors. you need to provide the following in your DB connection
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
More info can be seen Here

1.Add ERRMODE_EXCEPTION mode after your db connection:
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
2.And than you must use try{} catch{} method for all your mysql query. Like this:
try {
$SQL = "DELETE FROM items WHERE item_id=:item_id";
$m = $dbh->prepare($SQL);
$m->bindParam(':item_id', $item_id, PDO::PARAM_INT);
$m->execute();
//success
$return = "Your success message.";
}
catch (PDOException $e) {
//error
$return = "Your fail message: " . $e->getMessage();
}

You should use this:
return $exception->getMessage();
See the page on the documentation of Exception class:
http://www.php.net/manual/en/exception.getmessage.php

Related

My form won't send informations to my database [PHP] [duplicate]

This question already has answers here:
Why does this PDO statement silently fail?
(2 answers)
Closed last year.
I have an insert statement that is executed with PDO. Insert works great however if there is an error I would like it displayed to the user.
I have the below try-catch block.
try{
$insertuser = $db->prepare('INSERT INTO `she_she`.`Persons` (`idnumber`,`addedby`,`firstname`, `middlename`, `surname`, `fullname`, `gender`, `birthdate`, `homelanguage`, `department`, `employeetype`, `employeestatus`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)');
$insertuser->execute(array($idnumber,$user,$firstname, $middlename, $surname, $fullname, $gender, $birthdate, $language, $department, $employmenttype, $personstatus));
}
catch(PDOException $exception){
return $exception;
}
If the query fails, or let's say a duplicate IDNumber, I want this displayed to the user.
If I simply try to echo the variable $exception it does not work.
I want to return the MySQL error to the user.
By default PDO is not in a state that will display errors. you need to provide the following in your DB connection
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
More info can be seen Here
1.Add ERRMODE_EXCEPTION mode after your db connection:
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
2.And than you must use try{} catch{} method for all your mysql query. Like this:
try {
$SQL = "DELETE FROM items WHERE item_id=:item_id";
$m = $dbh->prepare($SQL);
$m->bindParam(':item_id', $item_id, PDO::PARAM_INT);
$m->execute();
//success
$return = "Your success message.";
}
catch (PDOException $e) {
//error
$return = "Your fail message: " . $e->getMessage();
}
You should use this:
return $exception->getMessage();
See the page on the documentation of Exception class:
http://www.php.net/manual/en/exception.getmessage.php

PHP PDO - There is no active transaction

I am having problem with transactions in php script. I would like to make multiply queries and be able to recall them all, if at least one of them fails. Below you can find a simple example of the script I am using:
$tags_input = array(6,4,5);
$conn = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8',
DB_USER, DB_PASSW, array(
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
$conn->beginTransaction();
$sql = "INSERT INTO projects (id, pr_id, enabled) VALUES ( :val0, :val1, :val2)";
$stmt = $conn->prepare($sql);
if(count($tags_input)>0){
for($i = 0;$i<count($tags_input);$i++){
$stmt->bindValue(':val0', 57);
$stmt->bindValue(':val1', $tags_input[$i]);
$stmt->bindValue(':val2', 'Y');
$result = $stmt->execute();
}
}
$res1 = $conn->commit();
$conn->rollBack();
Now, this example generates an error:
Uncaught exception 'PDOException' with message 'There is no active
transaction'
If I erase the line $conn->rollBack();, the error disappears. Therefore I cannot understand, why pdo object can't see open transaction (begintransaction and commit do not generate any errors). I also tried putting rollBack() inside the transaction, but made no difference. I was still getting an error 'There is no active transaction'.
I am running PHP 5.6 and Mysql tables on InnoDB.
Wrap your transaction code inside a try-catch statement.
//try {
$tags_input = array(6,4,5);
$conn = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8',
DB_USER, DB_PASSW, array(
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
} catch (Exception $e) {
die("Unable to connect: " . $e->getMessage());
}
try {
$conn->beginTransaction();
$sql = "INSERT INTO projects (id, pr_id, enabled) VALUES ( :val0, :val1, :val2)";
$stmt = $conn->prepare($sql);
if(count($tags_input)>0){
for($i = 0;$i<count($tags_input);$i++){
$stmt->bindValue(':val0', 57);
$stmt->bindValue(':val1', $tags_input[$i]);
$stmt->bindValue(':val2', 'Y');
$result = $stmt->execute();
}
}
$res1 = $conn->commit();
} catch (Exception $e) {
$conn->rollBack();
echo "Failed: " . $e->getMessage();
}
EDIT
A really well-based and straight-forward explanation of the answer was provided by Richard as a comment.
The reason you got error is because you were trying to close a transaction when it was already closed. beginTransaction opens one, and EITHER rollBack OR commit closes it. You have to avoid doing BOTH actions, meaning commit/rollback, for a single beginTransaction statement, or you'll get an error. The above try/catch code ensures that only one closing statement is executed.
Peter and Richards answers are already correct, but there is one little mistake in the code from the transaction structure (and i can't add a comment).
The $connection->beginTransaction() must be outside of the try-catch block. When you're start the beginTransaction() in the try-block and your Database Operations throws an exception, the catch-block doesn't know something from an active transaction. So, you get the same error:
"There is no active transaction".
So the structure should be as well:
Get the Connection.
Start the Transaction with $connection->beginTransaction()
Open the try-catch block.
The try-block contains the $connection->commit() after DB Operations.
The catch-block contains the $connection->rollback() before a throw Exception.
So your code should look like this:
$tags_input = array(6,4,5);
$conn = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8',
DB_USER, DB_PASSW, array(
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
} catch (Exception $e) {
die("Unable to connect: " . $e->getMessage());
}
//Begin Transaction
$conn->beginTransaction();
try {
$sql = "INSERT INTO projects (id, pr_id, enabled) VALUES ( :val0, :val1, :val2)";
$stmt = $conn->prepare($sql);
if(count($tags_input)>0){
for($i = 0;$i<count($tags_input);$i++){
$stmt->bindValue(':val0', 57);
$stmt->bindValue(':val1', $tags_input[$i]);
$stmt->bindValue(':val2', 'Y');
$result = $stmt->execute();
}
}
$res1 = $conn->commit();
} catch (Exception $e) {
$conn->rollBack();
echo "Failed: " . $e->getMessage();
}

pdoexception not outputting error

$db = new PDO('mysql:host=localhost;dbname=dbname;charset=utf8', 'username', 'password');
try
{
//Prepare and execute an insert into DB
$st = $db->prepare("INSERT INTO users(login,pass,email,county) VALUES(:username,:password,:email,:county)");
$st->execute(array(':username' => $_POST['username'], ':password' => $_POST['password1'], ':email' => $_POST['email'], ':county' => $_POST['county']));
echo 'Success';
}
catch (PDOException $e)
{
echo $e->getMessage();
}
Hi, I am not completely familiar with pdo but I thought I would add a few error exceptions, except I won't actually display the error normally as I don't want everyone to know my schema. In this case I changed my working code to a non working code by changing "...,county)" to "....,count)" which obviously did not insert into the database at all but still shown "Success" and no error.
Please help :(
You need to set PDO error mode to throw exception.
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

PHP PDO Error Message as a Variable to send in email

Making the switch to PDO from MySQL in PHP. In the past, when a query was ran and wasn't executed for whatever reason, I was able to send myself an email with the mysql_error() message in the body like so:
$query = "SELECT dogs FROM animals";
$res = mysql_query($query);
if (!$res) {
$error = "Error Message: " . mysql_error();
mail("my#email.com","Database Error",$error);
}
From that I would be alerted by an emil when something was wrong with the database on a website.
My PDO setup is as follows:
setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
I have a try catch in the PDO connection itself but I would like to get error messages for prepare and execute as they happen like so:
$query = "SELECT cats FROM animals";
$sql = $pdo->prepare($query);
if (!$sql->execute()) {
$error = "Error Message: " . (pdo error message here);
mail("my#email.com","Database Error",$error);
}
Any ideas on how to assign PDO error messages in an email subject? I'm able to get a logical error message if a prepare fails be using errorInfo() but on execute errors(such as invalid parameter counts for arrays), I can't seem to get an error message.
Thanks for any and all help.
Use try/catch
try {
$sql->execute();
} catch (PDOException $e) {
$e->getMessage(); // This function returns the error message
}
You can use:
$query = "SELECT cats FROM animals";
$sql = $pdo->prepare($query);
if (!$sql->execute()) {
$arr = $sql->errorInfo();
$error = print_r($arr, true);
mail("my#email.com","Database Error",$error);
}

How to Get Error Details From MySQL Stored Procedure

I am calling a mysql stored procedure using PDO in PHP
try {
$conn = new PDO("mysql:host=$host_db; dbname=$name_db", $user_db, $pass_db);
$stmt = $conn->prepare('CALL sp_user(?,?,#user_id,#product_id)');
$stmt->execute(array("user2", "product2"));
$stmt->setFetchMode(PDO::FETCH_COLUMN, 0);
$errors = $stmt->errorInfo();
if($errors){
echo $errors[2];
}else{
/*Do rest*/
}
}catch(PDOException $e) {
echo "Error : ".$e->getMessage();
}
that return below error because the name of the field in insert query was given wrong
Unknown column 'name1' in 'field list'
So i want to know if this is possible to get detailed error information something like:-
Unknown column 'Tablename.name1' in the 'field list';
that could tell me what column of which table is Unknown.
while creating the pdo connection, pass options like error mode and encoding:
The PDO system consists of 3 classes: PDO, PDOStatement & PDOException. The PDOException class is what you need for error handling.
Here is an example:
try
{
// use the appropriate values …
$pdo = new PDO($dsn, $login, $password);
// any occurring errors wil be thrown as PDOException
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$ps = $pdo->prepare("SELECT `name` FROM `fruits` WHERE `type` = ?");
$ps->bindValue(1, $_GET['type']);
$ps->execute();
$ps->setFetchMode(PDO::FETCH_COLUMN, 0);
$text = "";
foreach ($ps as $row)
{
$text .= $row . "<br>";
}
// a function or method would use a return instead
echo $text;
} catch (Exception $e) {
// apologise
echo '<p class="error">Oops, we have encountered a problem, but we will deal with it. Promised.</p>';
// notify admin
send_error_mail($e->getMessage());
}
// any code that follows here will be executed
I found this to be helpful for me. "error_log" prints to the php error log but you can replace with whatever way you'd like to display the error.
} catch (PDOException $ex){
error_log("MYSQL_ERROR"); //This reminds me what kind of error this actually is
error_log($ex->getTraceAsString()); // will show the php file line (and parameter
// values) so you can figure out which
// query/values caused it
error_log($ex->getMessage()); // will show the actual MYSQL query error
// e.g. constraint issue
}
p.s. I know this is a bit late but maybe it can help someone.

Categories