How to use lastinsertid() function [duplicate] - php

I've come across with a problem. My framework was working just fine with PHP 5.3.0. I upgraded my PHP version to PHP 5.4.x and I started to have few issues with some parts of my framework.
After PHP version upgrade, PDO lastInsterId() always returns 0.
I have auto-increment field called id.
It is adding the data to database without any problems.
For some reason I keep getting 0 as last insert id.
Here is my code;
databaseobjects.php
public static function create () {
global $db;
$attributes = self::sanitize(static::$fields);
$sql = "INSERT INTO ".PREFIX.static::$table_name." (";
$sql .= join(", ", array_keys($attributes));
$sql .= ") VALUE (:";
$sql .= join(", :", array_keys($attributes));
$sql .= ")";
return ($db->crudQuery($sql, $attributes)) ? true : false;
}
public static function lastInsertID () {
global $db;
return $db->handler->lastInsertId();
}
database.php
public function crudQuery($sql, $data) {
$sth = $this->handler->prepare($sql);
return $sth->execute($data);
}
First create() method is called, then crudQuery() method is called.
As I mentioned before, I can add the data successfully to MySQL database.
Unfortunately when I call lastInsterID() method, it always returns 0.
I will be really glad if you can help me out with this problem before I will get the last ID with SQL Query (:

Other than a bug in php/PDO or your framework, there are two possibilities. Either lastInsertId() is called on a different MySQL connection than the insert, or you are generating the id in your application/framework and inserting it, rather than letting auto_increment generate it for you. Which column in the table is the primary key/auto_increment? Is that column included in $attributes in your create() function?
You can test PDO to make sure that part is working correctly with this code (in a new file):
// Replace the database connection information, username and password with your own.
$conn = new PDO('mysql:dbname=test;host=127.0.0.1', 'user', 'password');
$conn->exec('CREATE TABLE testIncrement ' .
'(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50))');
$sth = $conn->prepare('INSERT INTO testIncrement (name) VALUES (:name)');
$sth->execute([':name' => 'foo']);
var_dump($conn->lastInsertId());
$conn->exec('DROP TABLE testIncrement');
When I ran this script, the output was
string(1) "1"

After you commit a transaction PDO::lastInsertID() will return 0, so best to call this method before the transaction is committed.

The one other problem could be using $pdo->exec($sql) instead of $pdo->query($sql).
exec($sql) will return always 0 when you use $pdo->lastInsertId(). So use query() instead.

I got a 0 when the last insert statement failed due to a foreign key contraint. last_error was a string.

When no exception is thrown, lastInsertId returns 0. However, if lastInsertId is called before calling commit, the right id is returned.
http://php.net/manual/es/pdo.lastinsertid.php

Related

Count number of rows inserted using Laravel? [duplicate]

I'm using raw queries with laravel 4, is there a way to check affected rows on an insert? DB::getPdo()->rowCount(); gives me an "undefined method" error. Code is as follows:
$query = "INSERT IGNORE INTO table (id) VALUES (?)";
$doQuery = DB::insert($query, array($value));
if ($doQuery) {
return DB::getPdo()->last();
} else {
return 0;
}
If not, is there an easy way to figure out whether an insert was done or not without making it two queries?
You can use this function:
int affectingStatement(string $query, array $bindings = array())
Run an SQL statement and get the number of rows affected.
Parameters
string $query
array $bindings
Return Value
int
This function is already documented for laravel 4.2 as well as for 5.4. [Edit note: The documentation for those versions are removed from the laravel site.]
Note that insert() is an alias for statement() and will return a boolean. While the functions update() and delete() are aliases for affectingStatement(). So if you want to be funny and confuse the reviewers you could also write $rowCount = DB::delete("INSERT IGNORE ...", $bindings) - and it will work.
Well I figured out a workaround that should be just as efficient - use INSERT INTO instead of INSERT IGNORE INTO and use try/catch.
$query = "INSERT INTO table (id) VALUES (?)";
try {
DB::insert($query, array($value));
return 1;
} catch (\Exception $e) {
return 0;
}

PHP MYSQL -> UPDATE column with variable if that variable isn't null or empty

Sorry, but i'm new to PHP, so i will look like a noob.
As the title says, i made this method which updates user data:
function update($userid, $name){
Try{
$stmt=$this->db->prepare("UPDATE users
SET
name=:name,
WHERE userid=:userid");
$stmt->execute(array(':name'=>$name));
} Catch(PDOException $e){
echo $e->getMessage();
}
}
That code is working right, but i want to know if it's possible, the "name" column just update if the variable coming from:
$user->update($userid, $name);
From $name, is not null or not empty. If it's null or Empty, the MYSQL UPDATE function should not be done.
Try this instead.
function update($userid, $name) {
try {
if (!empty($name) and !empty($userid)) {
$stmt = $this->db->prepare("UPDATE users
SET
name=:name
WHERE userid=:userid");
$stmt->execute(array(':name' => $name, ':userid' => $userid));
}
}
Catch(PDOException $e) {
echo $e->getMessage();
}
}
Explanation
Removal of the trailing comma.
As stated by #Fred -ii- you had a trailing comma in your SQL query after the SET (i.e SET name=:name,).
The comma in SQL queries are used to separate multiple updates from one another so UPDATE table SET col1 = "val1", col2 = "val2" and so on. Since you are only updating one column, you don't need the comma
The empty method checks whether the variable $name has been set and is not false. See documentation.
Removed the SQL-Injection-Vulnerable in :userid=$userid
Why i think it is better to have an if-statement inside the function
A function should be reusable and it costs nothing to call a function
In clean code you should avoid using if-statements, which means, you should not always have surround an if-statment before calling a function which could be called in other parts of the code, too. What happens when you add another parameter?
I know this is discussable.

Error with my database function create() in mysqli and php 7

I was using PHP 5.6 and mysql 5.5, I updated to mysql 5.7 and php 7 for better speed (cause I heard php 7 is really faster than 5.6).
So I had this database function to insert my news rows on any table of my database.
public function create() {
global $database;
$attributes = $this -> sanitized_attributes();
$sql = "INSERT INTO " . static::$table_name . " (";
$sql.= join(", ",array_keys($attributes));
$sql.= ") VALUES ('";
$sql.= join("', '",array_values($attributes));
$sql.= "')";
if ( $database -> query($sql) ) {
$this -> id = $database -> insert_id();
return true;
} else {
return false;
} // END - if ( $database -> query($sql) )
} // END - public function create()
now that I made the update and I try to check where the code is broken, I realized that I cannot enter any new row in any table.
I receive this error when I try to create a new row to any table:
Database Query failed: Incorrect integer value: '' for column 'id' at
row 1
I somehow know where the problem is, my first cell on any table is an integer ID that is set to AUTO INCREMENT .. the problem at the function above is at this line I think:
$sql.= join("', '",array_values($attributes));
this first value is always an integer and PHP 7 and MYSQL 5.7 want the value withOUT the quotes. Thats what I realized .. when I was using the old PHP 5.3 - 5.6, the same database function never had a problem ..
Any solution how to fix this DATABASE function so I can escape the quotes just for the INTEGER VALUES and let the QUOTES for the STRING VALUES .. ???

PHP, PDO & MYSQL : lastInsertId() returns NULL

I am rather new at PDO-based MySQL and I'm running into a problem.
This is the method I'm executing :
public function insert( $table, $data )
{
// utility functions to auto-format the statements
$keys = $this->getKeys($data);
$placeholders = $this->getPlaceholders($data);
$q = "INSERT INTO $table ($keys) VALUES ($placeholders)";
// this simply returns a new PDO object
$dbh = $this->createSession();
$stmt = $dbh->prepare($q);
$stmt->execute( array_values($data) );
return $dbh->lastInsertId();
}
After that, I run my method and store the returned value in a variable :
$new_user_id = $U->insert( $data );
var_dump($new_user_id);
And I get
NULL
Note the query is actually executed, and my data is correctly inserted into my table; no problem on that side. It seems it just can't grab the last insert ID as I ask for it.
Thanks for your time.
Not sure about any PDO-specific issues, but by default MySQL only returns an insert id if there's an auto_increment integer field in the database (generally but not necessarily the primary key). If your table doesn't include this nothing is returned by $dbh->lastInsertId()
I've reviewed the code again and I found that my value wasn't returned because of an intermediate method that wasn't passing the value correctly to the top-layer method.
Checking the value at the source shows no problem.
Thanks for the replies anyway.

PDO lastInsertId() always return 0

I've come across with a problem. My framework was working just fine with PHP 5.3.0. I upgraded my PHP version to PHP 5.4.x and I started to have few issues with some parts of my framework.
After PHP version upgrade, PDO lastInsterId() always returns 0.
I have auto-increment field called id.
It is adding the data to database without any problems.
For some reason I keep getting 0 as last insert id.
Here is my code;
databaseobjects.php
public static function create () {
global $db;
$attributes = self::sanitize(static::$fields);
$sql = "INSERT INTO ".PREFIX.static::$table_name." (";
$sql .= join(", ", array_keys($attributes));
$sql .= ") VALUE (:";
$sql .= join(", :", array_keys($attributes));
$sql .= ")";
return ($db->crudQuery($sql, $attributes)) ? true : false;
}
public static function lastInsertID () {
global $db;
return $db->handler->lastInsertId();
}
database.php
public function crudQuery($sql, $data) {
$sth = $this->handler->prepare($sql);
return $sth->execute($data);
}
First create() method is called, then crudQuery() method is called.
As I mentioned before, I can add the data successfully to MySQL database.
Unfortunately when I call lastInsterID() method, it always returns 0.
I will be really glad if you can help me out with this problem before I will get the last ID with SQL Query (:
Other than a bug in php/PDO or your framework, there are two possibilities. Either lastInsertId() is called on a different MySQL connection than the insert, or you are generating the id in your application/framework and inserting it, rather than letting auto_increment generate it for you. Which column in the table is the primary key/auto_increment? Is that column included in $attributes in your create() function?
You can test PDO to make sure that part is working correctly with this code (in a new file):
// Replace the database connection information, username and password with your own.
$conn = new PDO('mysql:dbname=test;host=127.0.0.1', 'user', 'password');
$conn->exec('CREATE TABLE testIncrement ' .
'(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50))');
$sth = $conn->prepare('INSERT INTO testIncrement (name) VALUES (:name)');
$sth->execute([':name' => 'foo']);
var_dump($conn->lastInsertId());
$conn->exec('DROP TABLE testIncrement');
When I ran this script, the output was
string(1) "1"
After you commit a transaction PDO::lastInsertID() will return 0, so best to call this method before the transaction is committed.
The one other problem could be using $pdo->exec($sql) instead of $pdo->query($sql).
exec($sql) will return always 0 when you use $pdo->lastInsertId(). So use query() instead.
I got a 0 when the last insert statement failed due to a foreign key contraint. last_error was a string.
When no exception is thrown, lastInsertId returns 0. However, if lastInsertId is called before calling commit, the right id is returned.
http://php.net/manual/es/pdo.lastinsertid.php

Categories