Get last inserted id after setting commit to false - php

I'm trying to insert data into two tables, if the insertion not work for one of them operation should ignored.(I think this called transaction)
try{
$dbcon=new mysqli($hn,$un,$pw,$dbn);
if($dbcon->connect_error)
throw new Exception($dbcon->connect_error);
$dbcon->autocommit(false);
$query="insert into users(id,email) values(null,'$email')";
$res_a=$dbcon->$query($query);
if($res_a){
$l_id=$res_a->insert_id;
$query="insert into profiles values($l_id,'$name','$birthday')";
$res_b=$dbcon->query($query);
}
if(!res_a || !res_b){
$dbcon->rollback();
throw new Exception("problem with database !!");
}
$dbcon->commit();
}catch(Exception $e){
echo $e->getMessage();
}finaly{
if(isset($dbcon))
$dbcon->close();
}
With this code PHP showing this Error : "Trying to get property of non-object" ...
In other words is there better way to do transaction without using autocommit methode (I'm working with mysqli)?

To answer the question and ignoring the issues with the error message this is how to run multiple updates within a transaction.
I would try retrieving the ->insert_id using the connection handle rather than the statement handle as the transaction/commit/rollback are all part of the connection handle and not the statement handle this appears to be more reliable and may be why you are not getting the error.
$dbcon=new mysqli($hn,$un,$pw,$dbn);
// if no connection can be made there is no point doing anything else
if($dbcon->connect_error) {
echo $dbcon->connect_error;
exit;
}
try{
//$dbcon->autocommit(false);
$dbcon->begin_transaction(); // this does the autocommit = false as well
$query = "insert into users(id,email) values(null,'$email')";
$res_a = $dbcon->$query($query);
if ( ! $res_a ) { // testing for FALSE is only safe way
throw new Exception($dbcon->error);
}
//$l_id = $res_a->insert_id;
$l_id = $dbcon->insert_id;
$query="insert into profiles values($l_id,'$name','$birthday')";
$res_b=$dbcon->query($query);
if( ! res_b) {
throw new Exception($dbcon->error);
}
$dbcon->commit();
}
catch(Exception $e){
echo $e->getMessage();
$dbcon->rollback();
}
finally{ // spelling correction
// not strictly necessary as PHP will close and cleanup automatically
if(isset($dbcon))
$dbcon->close();
}

Related

PHP file upload error conditions

I am trying to create a profile editing setup. It seems as though the information is edited only when an image is being uploaded. I found out that allowing the error message to be a condition allows for some more manipulation so I attempted it now my condition statement is not working as it should.
if($_FILES['files']['error']==0) {
print_r($_FILES['files']['error']);
echo "if";
foreach($_FILES['files']['name'] as $file => $name) {
$filename = $name;
try{
if(move_uploaded_file($_FILES['files']['tmp_name'][$file],'uploads/'.$filename)) {
$updateInfo = $db->prepare("UPDATE users SET image = :image, aboutme = :aboutme WHERE id = :id");
$updateInfo->bindParam(":image", $filename);
$updateInfo->bindParam(":id", $_SESSION['user']['id']);
$updateInfo->bindParam(':aboutme', $aboutme);
$updateInfo->execute();
}
} catch(Exception $e) {
echo $e;
}
}
} elseif($_FILES['files']['error'] == 4) {
print_r($_FILES['files']['error']);
echo "Elseif";
try{
$updateInfo = $db->prepare("
UPDATE users
SET
aboutme = :aboutme
WHERE id = :id
");
$updateInfo->bindParam(':id', $_SESSION['user']['id']);
$updateInfo->bindParam(':aboutme', $aboutme);
$updateInfo->execute();
} catch(Exception $e) {
echo $e;
}
} else{
print_r($_FILES['files']['error']);
echo "else";
}
}
When I check what array is being sent, its the correct one but the wrong condition, ie: it would run the else statement no matter the file check.
My question:
Is there something wrong with my code, with the exception of any security or efficiency flaws?
$_FILES['files']['error'] returns error code along with the file array. There are different type of error codes, all codes are mentioned in following link with details:
Please check by
print_r($_FILES['files'])
and see what are you getting in response.
As you posted your array response, you can get error code by $_FILES['files']['error'][0] or use switch case as mentioned in following link.
See here for more details:
http://php.net/manual/en/features.file-upload.errors.php
Also regarding debugging, always debug code step by step from top to bottom. Check $_POST, $_FILES, $_SERVER etc details if you get some problem particular related to data process.

Repeatedly try perform MySQL query with PHP

I have seen somewhere something like the code below. It is intended to make multiple attempts to perform a query if it has failed with anything else than deadlock error. I just want to ask you guys if is it a good practice or does it have any benefits?
$success = false;
$try_count = 5;
do{
try {
$this->_db->beginTransaction();
// PERFORM QUERY 1
// PERFORM QUERY 2
$this->_db->commit();
$success = true;
return true;
}catch(PDOException $e){
$this->_db->rollBack();
$try_count--;
$success = false;
// if not deadlock error, throw it
if($e->getCode()!=1213) throw $e;
if($try_count < 1) return false;
}
}while($try_count > 1 && !$success);
This is generally a bad practice unless you have a very good reason. I say this because you would have to add logic to see what caused the error and respond differently to each error before deciding to re-query the database. Cheers :)

I can not get this PDO insert query to work

Here is some code I am working on. I want to keep track of some data like my password to my online connections and want to be able to get the correct password back if I forget.
Here is my code that does not work.
if(isset($_GET['addform']))
{
include $_SERVER['DOCUMENT_ROOT'].'../rcadb/db.inc.php';
try
{
$sql='INSERT INTO rcainfo
SET
coname = :coname,
coemail = :coemail,
copassword = AES_ENCRYPT(:copassword, $passwordHelper) ';
$s = $pdo->prepare($sql);
$s->bindValue(':coname', $_POST['coname']);
$s->bindValue(':coemail', $_POST['coemail']);
$s->bindValue(':copassword', $_POST['copassword']);
$s->execute();
}
catch(PDOException $e)
{
$error = 'Error adding submitted Company Data';
include 'error.html.php';
exit();
}
header('Location:.');
exit();
}
I have a form that I enter the data into etc.
any help will be apreciated
Looks like you have an issue with your include:
include $_SERVER['DOCUMENT_ROOT'].'../rcadb/db.inc.php';
Try using require instead of include becuase it will throw an error. Include doesn not throw an error.
My guess is that you probably just want to do this
$include = '../rcadb/db.inc.php';
require $include;

Delete file if fail during transaction, how to recover/rollback query execute before

Delete file if fail during transaction, how to recover/rollback query execute before?
I need to delete files in transaction, is it possible to know if unlink file fail then means delete file fail then rollback the sql execute before..
and other question if execute query failed after unlink() how to recover file delete before?
like make unlink() apart of transaction
try{
$connect_db->beginTransaction();
// execute select query
// execute delete query
// .. execute other query
if (is_file($file_path)) {
if(unlink($file_path) == false) {
// How to recover/rollback delete query and other query execute before
$message = '';
return $message;
exit;
}
}
// ....execute other query
$connect_db->commit();
} catch (PDOException $e) {
$message = '';
}
return $message;
I think this is what you are looking for:
if( is_file($file_path) ) {
if( ! unlink($file_path) ) { // or if(unlink($file_path) == false) {
$connect_db->rollBack();
$message = '';
return $message;
exit;
}
}
As long as your DB supports transaction.
You might want to read the transaction documentation.

PDO:sqlite doesnt INSERT data, yet no error

try
{
$res = $db->exec($sql);
if ($res === FALSE)
{
print_r($db->errorInfo());
die();
}
}
catch(PDOException $e)
{
die($e->getCode().':'.$e->getMessage());
}
catch(Exception $e)
{
die($e->getCode().':'.$e->getMessage());
}
No error info, and neither does it get caught as an exception. Yet $res is FALSE and no data gets inserted.
Array
(
[0] =>
)
But when I echo $sql and enter that query in SQLiteManager, it works inserting the data.
I used sqlite only with Python, but I had to commit insert/update statements there... Maybe that's the case here too? http://docs.php.net/manual/en/pdo.commit.php
Ensure the directory where you store file is writable.

Categories