Prepared statements and how they affect queries - php

In an effort to make my scripts more secure, I have started using prepared statements to prevent mysql injection. This script inserts the data just fine, but getting the last inserted id (based on auto incrementation in the database) now returns 0 when it should return the correct id number.
This part inserts just fine.
$stmt = $conn->prepare("INSERT INTO users (userName) VALUES (?)");
$stmt->bind_param("s", $_SESSION['username']);
$stmt->execute();
This is where I am having problems. I am trying to get the last inserted ID of the user and it is returning 0.
// Get the last inserted ID for the users ID
$query = "SELECT LAST_INSERT_ID()";
$result = mysql_query($query);
if ($result) {
$nrows = mysql_num_rows($result);
$row = mysql_fetch_row($result);
$userId = $row[0];
}
This was working when I had my script before starting on Prepared Statements. The only thing I changed was adding the Prepared Statement to insert the data and my db connection is as follows:
$conn = new mysqli($server, $user, $password, $database) or die('Could not connect: ' . mysql_error());
I am a noob with php so any help would be greatly appreciated.

You may have a fundamental misunderstanding: When you switch to mysqli, your mysql_* functions will no longer use the same connection.
LAST_INSERT_ID() works on a per-connection basis.
You will have to make that query using the same library/connection as the main query, or as #zerkms points out, use $conn->insert_id.

mysqli_insert_id().

Related

Get last inserted ID in prepared statement

I need to get the last inserted ID for each insert operation and put it into array, I am trying to see what is the correct way of doing it.
Following this post Which is correct way to get last inserted id in mysqli prepared statements procedural style?
I have tried to apply it to my code but I am still not getting the right response.
if($data->edit_flag == 'ADDED')
{
$rowdata[0] = $data->location_name;
$rowdata[1] = 0;
$rowdata[2] = $data->store_id;
$query = "INSERT IGNORE INTO store_locations (location_name,total_items, store_id) VALUES (?,?,?)";
$statement = $conn->prepare($query);
$statement->execute($rowdata);
$id = mysqli_stmt_insert_id($statement);
echo "inserted id: " . $id;
}
I then realised that I am using a PDO connection so obviously mysqli functions wont work. I went ahead and tried the following
$id = $conn->lastInsertId();
echo "insert id: " . $id;
but the response is still empty? What am I doing incorrectly? For the lastInsertId(), should I be using $conn or $statement from here:
$statement = $conn->prepare($query);
$statement->execute($rowdata);
You are using lastInsertId() correctly according to the PDO:lastInsertId() documentation
$statement = $conn->prepare($query);
$statement->execute($rowdata);
$id = $conn->lastInsertId();
Some potential reasons why it is not working:
Is this code within a TRANSACTION? If so, you need to COMMIT the transaction after the execute and before the lastInsertId()
Since you INSERT IGNORE there is the potential that the INSERT statement is generating an error and not inserting a row so lastInsertId() could potentially be empty.
Hope this helps!
If you are using pdo,
$stmt = $db->prepare("...");
$stmt->execute();
$lastInsId = $db->lastInsertId();

PDO Prepared Statements and MSSQL databases not functioning correctly

I'm having a problem running prepared queries on a MSSQL database using PDO. I can connect to the database and run SELECT queries with no parameters, but now I'm trying to run a simple SELECT query with one parameter, :user. However, the code does not return any values, despite the fact that there definitely is a database row with that value in. Here's the code I'm using:
$db = new PDO('dblib:host='.$dbHost.';dbname='.$dbName.';charset=utf8mb4',$dbUser, $dbPass);
$stmt = $db->prepare('SELECT * FROM customer WHERE email_address = :user ');
$stmt->bindValue(":user", $_SESSION["username"], PDO::PARAM_STR);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
I receive no output from the var_dump. I know that in the database there is a correct row, so I tried:
$stmt = $db->prepare("SELECT * FROM customer WHERE email_address = 'the#email.com'");
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
And yet still no value was returned. Am I doing something wrong with PDO? If I type this exact query into the query bar it runs.
you forgot to execute your query.
right after the paramter binding, put this code:
$stmt->execute();
Ok, I'm an idiot. Forgot to execute the query. Amended code for people in the same predicament:
$db = new PDO('dblib:host='.$dbHost.';dbname='.$dbName.';charset=utf8mb4',$dbUser, $dbPass);
$stmt = $db->prepare('SELECT * FROM customer WHERE email_address = :user ');
$stmt->bindValue(":user", $_SESSION["username"], PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);

how can I retrieve the hashed password from mySql database with php?

My question supposed to be simple! although, I couldn't find the correct answer!
I need to retrieve the "hashed password" for the giving "username" from mySql database with php, then I need to store it in a variable, how could I do that?
All what I get is "Resource id #5"!
This is my code:
$query = "SELECT hashed_password ";
$query .= "FROM users ";
$query .= "WHERE username = '{$username}' ";
$query .= "AND hashed_password = '{$hashed_password}' ";
$query .= "LIMIT 1";
$result_set = mysql_query($query);
echo "$result_set";
echo '</br>';
To start off, let's use a MySQL library that supports prepared statements - otherwise, we'll run into SQL Injection issues in the future. Now, back to the actual question / answer.
If we use MySQLi, we have a few functions that will help us. Here's an example of an answer to your question w/ code comments to help walk through it:
// create our db connection
$mysqli = new mysqli('localhost', 'db_username', 'db_password', 'db_table');
// create a Prepared Statement to query to db
$stmt = $mysqli->prepare('SELECT hashed_password FROM users WHERE username = ? LIMIT 1');
// dynamically bind the supplied "username" value
$stmt->bind_param('s', $username);
// execute the query
$stmt->execute();
// get the first result and store the first column in the `$hashed_password` variable
$stmt->bind_result($hashed_password);
$stmt->fetch();
// close our Prepared Statement and the db connection
$stmt->close();
$mysqli->close();
echo $hashed_password;
Check out the PHP Doc for mysqli::prepare() for more examples =]
Note: I highly recommend avoiding the mysql_query() (and family) functions. They are not only deprecated, but they are quite insecure to use.
You need to fetch the data out of the mysql-resource that is returned by a query.
Just pass it through mysql_fetch_assoc($result_set). It will return your data in a nice and ordered arraay, moving ahead one row every call.
Meaning you can do
while ($row = mysql_fetch_assoc($result_set).
Also, please use mysqli. Its basically the same just with mysqli instead of mysql in commands. See the docs here for more info: http://php.net/manual/en/book.mysqli.php

How can I write a php code for data can not find in table of MySQL database?

I am so sorry mybe it is a silly question but as I am new in web language and php I dont know how to solve this problem.
I have a code which is getting ID from user and then connecting to MySQL and get data of that ID number from database table and then show on webpage.
But I would like to what should I add to this code if user enter an ID which is not in table of database shows a message that no data found.
Here is my code:
<?php
//connect to the server
$connect = mysql_connect ("localhost","Test","Test") ;
//connection to the database
mysql_select_db ("Test") ;
//query the database
$ID = $_GET['Textbox'];
$query = mysql_query (" SELECT * FROM track WHERE Code = ('$ID') ");
//fetch the results / convert results into an array
$ID = $_GET['Textbox'];
WHILE($rows = mysql_fetch_array($query)) :
$ID = 'ID';
echo "<p style=\"font-color: #ff0000;\"> $ID </p>";
endwhile;
?>
Thank You.
Sorry if it is so silly question.
You should use PDO (great tutorial here: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers ). This way, you can develop safer applications easier. You need to prepare the ID before inserting it to the query string, to avoid any user manipulation of the mysql query (it is called sql injection, guide: http://www.w3schools.com/sql/sql_injection.asp ).
The main answer to your question, after getting the results, you check if there is any row in the result, if you got no result, then there is no such an ID in the database. If you use PDO statements $stmt->rowCount();.
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password');
$stmt = $db->prepare("SELECT * FROM table WHERE Code=?");
$stmt->bindValue(1, $id, PDO::PARAM_INT); // or PDO::PARAM_STR
$stmt->execute();
$row_count = $stmt->rowCount();
if ($row_count > 0) {
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
//results are in $results
} else {
// no result, no such an ID, return the error to the user here.
}
Another reason to not use mysql_* functions: http://php.net/manual/en/migration55.deprecated.php

mysqli prepared statement without bind_param

I have this code for selecting fname from the latest record on the user table.
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
$sdt=$mysqli->('SELECT fname FROM user ORDER BY id DESC LIMIT 1');
$sdt->bind_result($code);
$sdt->fetch();
echo $code ;
I used prepared statement with bind_param earlier, but for now in the above code for first time I want to use prepared statement without binding parameters and I do not know how to select from table without using bind_param(). How to do that?
If, like in your case, there is nothing to bind, then just use query()
$res = $mysqli->query('SELECT fname FROM user ORDER BY id DESC LIMIT 1');
$fname = $res->fetch_row()[0] ?? false;
But if even a single variable is going to be used in the query, then you must substitute it with a placeholder and therefore prepare your query.
However, in 2022 and beyond, (starting PHP 8.1) you can indeed skip bind_param even for a prepared query, sending variables directly to execute(), in the form of array:
$query = "SELECT * FROM `customers` WHERE `Customer_ID`=?";
$stmt = $db->prepare($query);
$stmt->execute([$_POST['ID']]);
$result = $stmt->get_result();
$row = $result->fetch_assoc();
The answer ticked is open to SQL injection. What is the point of using a prepared statement and not correctly preparing the data. You should never just put a string in the query line. The point of a prepared statement is that it is prepared. Here is one example
$query = "SELECT `Customer_ID`,`CompanyName` FROM `customers` WHERE `Customer_ID`=?";
$stmt = $db->prepare($query);
$stmt->bind_param('i',$_POST['ID']);
$stmt->execute();
$stmt->bind_result($id,$CompanyName);
In Raffi's code you should do this
$bla = $_POST['something'];
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
$stmt = $mysqli->prepare("SELECT `fname` FROM `user` WHERE `bla` = ? ORDER BY `id` DESC LIMIT 1");
$stmt->bind_param('s',$_POST['something']);
$stmt->execute();
$stmt->bind_result($code);
$stmt->fetch();
echo $code;
Please be aware I don't know if your post data is a string or an integer. If it was an integer you would put
$stmt->bind_param('i',$_POST['something']);
instead. I know you were saying without bind param, but trust me that is really really bad if you are taking in input from a page, and not preparing it correctly first.

Categories