I do not understand what my problem seem to be.
I got the following PHP code:
include_once 'db.inc.php';
try
{
$db = new PDO(DB_INFO, DB_USER, DB_PASS);
}
catch(PDOException $e)
{
echo 'Connection failed: ', $e->getMessage();
exit();
}
$title = htmlentities($_POST['title']);
$entry = htmlentities($_POST['entry']);
$sql = "INSERT INTO entries (title, entry) VALUES (?, ?)";
$stmt = $db->prepare($sql);
$stmt->execute(array($title, $entry));
$stmt->closeCursor();
I do not receive any error of any kind and the script seem to have worked however it does not insert anything into the database.
No matter what I try it doesn't do anything.
edit
Sorted :)
I didn't know about $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);.
It gave me "Uncaught exception 'PDOException' with message 'SQLSTATE[3D000]: Invalid catalog name: 1046 No database selected'".
Turns out I wrote mysql:host=127.0.0.1;db_name=test1 instead of mysql:host=127.0.0.1;dbname=test1 in my config file.
Thank you very much for help!
Set PDO to throw exceptions when execution fails
$db = new PDO(DB_INFO, DB_USER, DB_PASS);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Related
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();
}
I am trying to use $dbc->connect_error to check if any error occurs while trying to connect to my databease. I always get an error page saying:
Notice: Undefined property: PDO::$connect_error in
C:\xampp\htdocs\add_products_processing.php on line 7
I am using Windows7 with XAMPP v3.2.2. The full code is shown below. I am sure that the username and the password are correct. Any advice?
<?php
$dsn = 'mysql:host=localhost;dbname=technoglance';
$username = 'root';
$password = 'password';
$dbc = new PDO($dsn, $username, $password);
if ($dbc->connect_error) {
die("Connection failed: " . $dbc->connect_error);
}
$main_class =filter_input(INPUT_POST, 'main_class');
$brand =filter_input(INPUT_POST, 'brand');
$model =filter_input(INPUT_POST, 'model');
$description =filter_input(INPUT_POST, 'description');
$quantity =filter_input(INPUT_POST, 'quantity');
$adding_date =filter_input(INPUT_POST, 'adding_date');
$sell_price =filter_input(INPUT_POST, 'sell_price');
$buying_price =filter_input(INPUT_POST, 'buying_price');
if(!empty($main_class)){
try{
$query = "INSERT INTO products (main_class, brand, model, description, quantity, adding_date, sell_price, buying_price ) VALUES ('$main_class', '$brand', '$model', '$description', '$quantity', now(),'$sell_price', '$buying_price' );";
// set the PDO error mode to exception
$dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbc->exec($query);
echo "Thank you. The record has been sent successfully.<br><br>";
}
catch(PDOException $e){
echo $query . "<br>" . $e->getMessage()."<br><br>";
}
}
else{
echo '<h1>Please use the contact form or don\'t leave an empty field!</h1>';
}
?>
Here is what your code should be
<?php
$dsn = 'mysql:host=localhost;dbname=technoglance;charset=utf8';
$username = 'root';
$password = 'password';
$dbc = new PDO($dsn, $username, $password);
$dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// filtering omitted
if(!empty($main_class)){
$query = "INSERT INTO products (main_class, brand, model, description, quantity, adding_date, sell_price, buying_price ) VALUES (?,?,?,?,?,?,?,?);";
$data = [$main_class,$brand,$model,$description,$quantity,$adding_date,$sell_price,$buying_price];
$dbc->prepare($query)->execute($data);
echo "Thank you. The record has been sent successfully.<br><br>";}
else{
echo '<h1>Please use the contact form or don\'t leave an empty field!</h1>';
}
PDO will report it's errors already, without any extra code required.
and you should be using prepared statements
If we have a look at the PDO manual and look up for the PDO class there is no connect_error property anywhere. But if we check mysqli manual we see it right there. You have to choose a database library and stick to it, they cannot be mixed.
I always recommend to configure PDO to throw exceptions as you already do (although connection errors in particular will always through an exception no matter your settings) and not care to catch them unless you want to do something specific with them.
There is no connect_error. You should use exception:
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
Or if you do not want exception you can try errorCode and errorInfo
i had installed freestyle extension in joomla (to allow php code in articles) im trying to access to a database in mysql with the next code
try {
$conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password)
$sql = "SELECT id, nombre, edad
FROM Prueba";
$q = $conn->prepare($sql);
$q->execute(array('%son'));
$q->setFetchMode(PDO::FETCH_ASSOC);
while ($r = $q->fetch()) {
echo sprintf('%s <br/>', $r['nombre']);
}
} catch (PDOException $pe) {
die("Could not connect to the database $dbname :" . $pe->getMessage());
}
?>
And i get this error in the article and i dont know why this is happening
Parse error: syntax error, unexpected T_VARIABLE on line 13
$conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password)
should be
$conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
(You're missing a ';')
Also I think your code isn't going to work exactly as planned since your SQL has no variables but you attempt to pass one to $q->execute() but I'm sure you can sort out what you're trying to do yourself...
I'm making a register script and using PDO for the first time, but I get this error when trying to use it. The defines works fine when use MySQLi.
My code gives me this error:
Array ( [0] => SQLSTATE[3D000]: Invalid catalog name: 1046 No database selected )
This is the code: (/register.php)
try{
$input_password_hash = password_hash($input_password, PASSWORD_DEFAULT);
$stmt = $PDO_new->prepare("SELECT user_name FROM users WHERE user_name = :username");
$stmt->bindParam(":username",$input_username);
$stmt->execute();
echo "code after exec";
//checks if user already exist in database.
if($stmt->rowCount()>0){
$error[] = "Username already exist";
echo "user is there";
}
else{
echo "user not there";
$insert = "INSERT INTO users(user_name, user_password_hash, user_email) VALUES($input_username,$input_password_hash, $input_email)";
}
} catch(PDOException $e){
$error[] = $e->getMessage();
}
This is the file for connecting to the databse: ((config/db_connect.php)
<?php
require_once($_SERVER['DOCUMENT_ROOT']."/config/db.php");
$PDO_new = new PDO("mysql:host=" . DB_HOST . ";DBName=" . DB_NAME, DB_USER, DB_PASS);
$PDO_new->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
And this is the file where I define the info for the database: (/config/db.php)
define("DB_HOST", "localhost");
define("DB_NAME", "username_databasename");
define("DB_USER", "username_admin");
define("DB_PASS", "password");
A quick test reveals that a PDO connection is case-sensitive in how it parses attributes. You use DBName when you should be using the lowercase dbname. This is not explicitly stated in the PDO::__construct() docs, as far as I can tell, but I was able to verify it testing in my own environment.
$PDO_new = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASS);
//--------------------------------------------^^^^^^^^^^
It is unclear why you are also establishing a connection via MySQLi, as MySQLi and PDO are comparable but incompatible APIs. You generally need one or the other, not both (unless you are combining code from 2 sources that use opposite APIs).
It is recommended to wrap the new PDO() in a try/catch to catch connection errors before setting ERRMODE_EXCEPTION on it.
try {
$PDO_new = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASS);
} catch (PDOException $e) {
// handle a connection error error
}
Finally, I would be remiss if I did not point out that you have plain variables in the INSERT statement rather than bound parameters. You should be binding values with placeholders here as you did in the first SELECT statement.
// Use placeholders please!
$insert = "INSERT INTO users(user_name, user_password_hash, user_email) VALUES(:input_username,:input_password_hash, :input_email)";
// prepare() then execute()...
I am new in php and have seen many post related to this error but still can not find the problem. I also tried with the try catch block and did not get the exception. There is no connection problem and have also tested the query in my database.
$host="mysql:host=".$host_name.";dbname=".$dbname;
$ques_code=1;
$dbh = new PDO($host, $dbuser, $dbpass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$S=$dbh->prepare("SELECT q_code FROM question_code_submission WHERE q_num = :id");
$S->bindParam(':id', $ques_code);
$temp_name=$S->execute();
$code_name=$temp_name->fetch(PDO::FETCH_ASSOC);
$code_name=$code_name['q_code'];
$S->execute() returns true or false, so $temp_name is being set to a boolean value - which explains why you can't call $temp_name->fetch() - it's not an object.
You don't need $temp_name at all, simply:
$S->execute();
$code_name = $S->fetch(PDO::FETCH_ASSOC);
$host="mysql:host=".$host_name.";dbname=".$dbname;
$ques_code=1;
$dbh = new PDO($host, $dbuser, $dbpass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$S=$dbh->prepare("SELECT q_code FROM question_code_submission WHERE q_num = :id");
$S->bindParam(':id', $ques_code);
$success = $S->execute();
if(!$success){
echo "Query failed !!";
}else{
$result=$S->fetch(PDO::FETCH_ASSOC);
$code_name = $result['q_code'];
echo $code_name;
}