PDO Delete Query in PHP does not take effect - php

I am using the below code to delete all rows from the mysql table but it does not take any effect. I am also not getting any errors - it just says record Record deleted successfully. I don't know if there is any backend safe mode enabled or I need to do additional commits but all the data is still in the database.
<?php
try {$pdo = new PDO("mysql:host=mysql;dbname=menu;charset=utf8mb4", "user",
"pass", array(PDO::ATTR_PERSISTENT => true));
} catch (\PDOException $e) {throw new \PDOException($e->getMessage(), (int)$e->getCode());};
$org = "1";
try {
$sql = "DELETE FROM menu where org=?";
$pdo->prepare($sql)->execute([$org]);
echo "Record deleted successfully";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
?>

Related

PDO and query troubleshoot - basic

I am converting an old php 5.6 code to 7.2 and learning how to use PDO.
I have reached a point where I got stuck and would like to learn from the community.
I created a test file structure:
db.php:
<?php
try {
$conn = new PDO($initlocation, $username, $pwdata);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "worked"; // THIS WORKS ON THE SCREEN
}
catch(PDOException $e){
echo "Connection failed: " . $e->getMessage();
}
?>
test.php:
<?php
include("db.php");
$user_query='SELECT * FROM `users` WHERE `email`="user1.a#gmail.com"';
echo $user_query; // I GET THE QUERY PRINTED ON THE SCREEN
echo is_object($conn); // THIS IS 1 WHICH IS GOD
echo "<br>";
echo is_object($res); // THIS IS 1 WHICH IS ODD
try{
$res = $conn->query($user_query);
}
catch (Exception $e){
echo "Query failed: " . $e->getMessage(); // NOTHING
}
echo "<br>";
echo is_object($res); // NOTHING
$data_exists = $res->fetch();
if ($data_exists==1) echo "yes"; // NOTHING
?>
I have left the testing method in the code as well and I am keen to find a better solution to find out why the query does not show anything.
The aim would be to find the email address in the DB and give me some feedback about it. Thank you in advance all the comments I will only learn form them.
Additional info:
When I run the SQL query in the DB directly it does give me the record that has the same email.
Try the following and use prepared statements like protection from SQL injections.
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
$user = $stmt->fetch();

Prevent submission of words already stored in database and echo an alert notifying user that his submission already exists

Everything works with my site and database.
I've submitted a snippet of code where I think the PHP to prevent duplicate submissions needs to be inserted.
{
$pdo = new PDO('mysql:host=localhost;dbname=', '', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec('SET NAMES "utf8"');
}
catch (PDOException $e)
{
$error = 'Unable to connect to the database server.';
include 'error.html.php';
exit();
}
if (isset($_POST['profanetext']))
{
try
{
$sql = 'INSERT INTO profane SET
profanetext = :profanetext,
profanedate = CURDATE()';
$s = $pdo->prepare($sql);
$s->bindValue(':profanetext', $_POST['profanetext']);
$s->execute();
}
catch (PDOException $e)
{
$error = 'Error adding submitted profanity: ' . $e->getMessage();
include 'error.html.php';
exit();
}
header('Location: .');
exit();
}
You do a select where query to see if the value exist first.
Also you can make the actual profane text database column UNIQUE. This will prevent insertion of duplicate value and will produce an db error if trying to do so.
Well, I figured out a way to make it work. After changing the profanetext column from TEXT type to VARCHAR(255) -- which allowed me to make the column UNIQUE -- I added this to my php to make the db error message display as an alert:
catch (PDOException $e)
{
$error = 'Error adding submitted profanity: ' . $e->getMessage();
echo '<script language="javascript">';
echo 'alert("That profanity has already been submitted")';
echo '</script>';
exit();
}

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();
}

Insertion of data into database using php

I'm new to php I have created a php form that will insert data into the database my database name is Emp and the table name is info. I'm inserting using PDO. I have written a code to do this and it is getting executed without catching any errors, but the database is still empty. I have posted my code below please tell me what I'm doing wrong.
<?php
try{
echo $_POST['name'].", ".$_POST['age'].", ".$_POST['email'].", ".$_POST['name'].", ".$_POST['country'].", ". $_POST['city'] ;
$user="root";
$pass="root123";
$con=new PDO('mysql:host=localhost;dbname=Emp', $user, $pass);
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$con->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$con->beginTransaction();
//echo "INSERT INTO info(Empid,Ename,Age,Email,Country,City,Salary) VALUES('".$_POST['eid']."','".$_POST['name']."','".$_POST['age']."','".$_POST['email']."','".$_POST['country']."','".$_POST['city']."','".$_POST['salary']."')";
$num=$con->exec("INSERT INTO info(Empid,Ename,Age,Email,Country,City,Salary) VALUES('".$_POST['eid']."','".$_POST['name']."','".$_POST['age']."','".$_POST['email']."','".$_POST['country']."','".$_POST['city']."','".$_POST['salary']."')");
echo "<br>".$num." row added succesfully"; // this is displayed when I execute this but database is empty.
}
catch(Exception $e)
{
echo 'Exception -> ';
var_dump($e->getMessage());
}
?>
Since you have used beginTransaction(), you have to commit the changes. Add
$con->commit();
Reference: PHP Manual
Note: Even though you are using PDO, you are still interpolating HTTP Request values without sanitization, that could be bad
you either have to commit or rollback the transaction ..
changes made to the database via the PDO transactions are not committed until you end the transaction by calling PDO::commit() or Calling PDO::rollBack()
<?php
try{
echo $_POST['name'].", ".$_POST['age'].", ".$_POST['email'].", ".$_POST['name'].", ".$_POST['country'].", ". $_POST['city'] ;
...
$con->beginTransaction();
....
$con->commit();
}
catch(Exception $e)
{
echo 'Exception -> ';
var_dump($e->getMessage());
$con->rollBack();
}
?>
All you need to do is to commit and/or rollBack your code
<?php
try{
.
. code
.
$con->beginTransaction();
.
. code
.
$num=$con->exec("INSERT INTO info (Empid,Ename,Age,Email,Country,City,Salary) VALUES('".$_POST['eid']."','".$_POST['name']."','".$_POST['age']."','".$_POST['email']."','".$_POST['country']."','".$_POST['city']."','".$_POST['salary']."')");
$con->commit(); // This is missing
}
catch(Exception $e)
{
var_dump($e->getMessage());
$con->rollBack(); // And this is missing
}
?>

PDO returns integer columns as String in PHP5.4

First of all, I am aware that there are various similar questions on SO such as this and this. However, when I fetch values from a table, integers are always fetched as string.
I am using PHP5.4 (5.4.16-1~dotdeb.1) and MYSQL5.5 (5.5.31+dfsg-0+wheezy1). It is written here that MySQL Native Driver is enabled by default in PHP5.4.0. But I still get string values.
I initialize a PDO object as follows.
try {
$dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8';
$db = new PDO($dsn,DB_USER,DB_PASS);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch (PDOException $e) {
header('HTTP/1.1 500');
exit;
} catch (Exception $e) {
header('HTTP/1.1 500');
exit;
}
When I insert, I tried to use execute(array(...)) format and also used bindValue(...,PDO::PARAM_INT), but they did not make a difference.
For example, here is how I insert a new row.
public function insertList ($db,$account_id,$list_name) {
$sql = $db->prepare('INSERT INTO lists VALUES (?,?,?,?,?)');
try {
// $sql->execute(array($list_name,0,0,0,$account_id));
$sql->bindValue(1,$list_name,PDO::PARAM_STR);
$sql->bindValue(2,0,PDO::PARAM_INT);
$sql->bindValue(3,0,PDO::PARAM_INT);
$sql->bindValue(4,0,PDO::PARAM_INT);
$sql->bindValue(5,$account_id,PDO::PARAM_INT);
$sql->execute();
} catch (PDOException $e) {
header('HTTP/1.1 500');
exit;
} catch (Exception $e) {
header('HTTP/1.1 500');
exit;
}
}
Here is how I fetch rows from a table
public function fetchLists ($db,$account_id) {
$sql = $db->prepare('SELECT * FROM lists WHERE account_id=?');
try {
$sql->execute(array($account_id));
$result = $sql->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
header('HTTP/1.1 500');
exit;
} catch (Exception $e) {
header('HTTP/1.1 500');
exit;
}
return $result;
}
This did not occur when I tested on XAMPP for Linux 1.8.1 which uses PHP5.4.7. I currently use nginx instead of Apache.
What is wrong?
To get integers and floats with respective types from mysql with PDO, you need both mysqlnd-based PDO-mysql and emulation mode turned off.

Categories