mysqli prepared statement with ADDTIME CURTIME fails - php

There are so many questions on SO for failed prepared statements, but I cannot find one which solves my exact problem (or explains it, atleast).
I'm trying to give my users a login-token which is valid for 5 minutes.
When I execute the query through PHPMyAdmin it works just fine:
WORKING QUERY
INSERT INTO LOGGEDIN (userID, loggedInToken, loggedInRefresh) VALUES
(1, "HJKFSJKFDSKLJFLS", ADDTIME(CURTIME(), '00:05:00'));
However, when trying to execute the query through PHP using a prepared statement it fails.
$stmt = $this->conn->prepare("INSERT INTO LOGGEDIN VALUES (userID, loggedInToken, loggedInRefresh) VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))");
$stmt->bind_param("is", $userID, $token);
I get the error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))' at line 1
It is the exact same query so I think it's due to how the prepare handles the query.
I've also tried entering the '00:05:00' as a variable because I thought the ' was causing the error but it fails as well.
$five_minutes = '00:05:00';
$stmt->bind_param("iss", $userID, $token, $five_minutes);
When I remove the prepare and use the following query:
$query = "INSERT INTO LOGGEDIN VALUES (userID, loggedInToken, loggedInRefresh) VALUES (" . $userID . ", '" . $token . "', ADDTIME(CURTIME(), '00:05:00'))";
if ($result = $mysqli->query($query)) {
...
It works fine but I would like to keep my code consistent and use a prepared statement everywhere I can.
How can I let this query execute properly using a prepared statement? If all else fails I think I could create the timestamp in PHP and pass it through to the database thus bypassing the whole ADDTIME calculation, but I would like to know what is causing the problem in the first place.
Problems need to be understood, not dodged.

You have a superfluous VALUES on your query:
$stmt = $this->conn->prepare("INSERT INTO LOGGEDIN VALUES (userID, loggedInToken, loggedInRefresh) VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))");
^^
Remove that:
$stmt = $this->conn->prepare("INSERT INTO LOGGEDIN (userID, loggedInToken, loggedInRefresh) VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))");

Related

MYSQL Syntax error in php but sql is valid

I'm trying to start a transaction is mysql and insert data into the database. The database source sql can be found on github here. Here is the error:
Error: START TRANSACTION; INSERT INTO Books(Title, PublicationDate,
PurchaseDate, Description, LocationID, GenreID) VALUES('Simple
Genius', '2008-4-1','2009-5-7','','Hardbook Library','Fiction'); SET
#bookid = LAST_INSERT_ID(); INSERT INTO BookAuthors(FirstName,
MiddleName, LastName) VALUES('David', '', 'Baldacci'); SET #authorid =
LAST_INSERT_ID(); INSERT INTO AuthorsInBooks(AuthorID, BookID)
VALUES(#authorid, #bookid); COMMIT; You have an error in your SQL
syntax; check the manual that corresponds to your MySQL server version
for the right syntax to use near 'INSERT INTO Books(Title,
PublicationDate, PurchaseDate, Description, LocationID,' at line 3
Near 'INSERT INTO Books(Title, PublicationDate, PurchaseDate, Description, LocationID,' doesn't make sense to me because it is missing GenreID after LocationID. Am i missing something? When I copy and paste this code into phpmyadmin it works fine. My php version is 5.4.
Here is php code:
$sql = "
START TRANSACTION;
INSERT INTO Books(Title, PublicationDate, PurchaseDate, Description, LocationID, GenreID)
VALUES('".$Title."', '".$YearWritten."','".$YearPurchased."','".$Description."','".$Location."','".$Genre."');
SET #bookid = LAST_INSERT_ID();
INSERT INTO BookAuthors(FirstName, MiddleName, LastName)
VALUES('".$AuthFirstName."', '".$AuthMiddleName."', '".$AuthLastName."');
SET #authorid = LAST_INSERT_ID();
INSERT INTO AuthorsInBooks(AuthorID, BookID)
VALUES(#authorid, #bookid);
COMMIT;
";
if (mysqli_query($conn, $sql)) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}
mysqli_close($conn);
mysqli_query() can only execute 1 query, if you want to execute multiple queries, you need:
if (mysqli_multi_query($conn, $sql)) {
In response to your comment "Can I see an example of what you mean #eggyal ?":
// mysqli provides API calls for managing transactions
mysqli_autocommit($conn, false);
// parameterise variables - NEVER concatenate them into dynamic SQL
$insert_book = mysqli_prepare($conn, '
INSERT INTO Books
(Title, PublicationDate, PurchaseDate, Description, LocationID, GenreID)
VALUES
(?, ?, ?, ?, ?, ?)
');
// bind the variables that (will) hold the actual values
mysqli_stmt_bind_param(
$insert_book,
'siisss', // string, integer, integer, string, string, string
$Title, $YearWritten, $YearPurchased, $Description, $Location, $Genre
);
// execute the statement (you can change the values of some variables and
// execute repeatedly without repreparing, if so desired - much faster)
mysqli_stmt_execute($insert_book);
// mysqli provides API calls for obtaining generated ids of inserted records
$book_id = mysqli_insert_id($conn);
// ... etc ...
// use the API call to commit your transaction
mysqli_commit($conn);
// tidy up
mysqli_stmt_close($insert_book);
Note that I've not included above any error detection/handling, which you'd certainly want to include in any real-world code.

prepared INSERT statement to get insert_id to use in a second prepared INSERT statement

Im trying to create my own register form but im having issues with prepared statements.
the idea is to create a prepared statement to insert info into the user table, then from that get the insert_id from the generated content to use in another insert statement
here is a version of my register script
<?php
$returnedId = '';
include "includes/dbconnect.php";
$stmt = $db->prepare("INSERT INTO `users`(`Username`, `Email`, `Password`) VALUES (?, ?, ?)");
$stmt->bind_param('sss', $_POST['username'], $_POST['email'], $_POST['password']);
$stmt->execute();
$returnedId = $stmt->insert_id;
$stmt->close();
echo $returnedId;
$allergystmt = $db->prepare("INSERT INTO 'user_allergy' ('user_id', 'allergy_id') VALUES (?, ?)");
$allergystmt->bind_param('ss', $returnedId, $_POST['check_list']);
$allergystmt->execute();
$allergystmt->close();
header('Location: index.php');
?>
the first prepared statement runs correctly and inserts information into the table, after that the $returnId variable is successfully echoed. next in the script is my second prepared statement, when it tries to run im getting the error that says:
Fatal error: Call to a member function bind_param() on a non-object in D:\filepath\register.php on line 17
it seems that my variable isnt being carried into the second prepared statement.
Your second query has syntax errors and failed to prepare. Since you have no error handling for database failures like this, your later code just blunders onwards:
$allergystmt = $db->prepare("INSERT INTO 'user_allergy' ('user_id', 'allergy_id') VALUES (?, ?)");
^--- ^--^--- ^-- etc...
You cannot use ' quotes on table and field names. ' indicate strings. None of those field/table names are reserved words, so there is NO need to quote them at at all:
$allergystmt = $db->prepare("INSERT INTO user_allergy (user_id, allergy_id) VALUES (?, ?)");
if (!$allergystmt) { die($dbh->errorInfo()); }
Note the addition of the errorInfo() output. Never assume a DB operation was successful. Always assume failure, and treat success as a pleasant surprise.

The values passed through Insert into query doesn't display in rows. But a new row is added

When I send below query to the database from a php page, the passed values are not displaying. But each time a newrow is added.
$query1="INSERT INTO login(username,password,type)
VALUES("."'".$m_nic."',"."'".$f_name."',"."'".$type."')";
$login_set=mysql_query($query1,$connection);
How can I prevent SQL injection in PHP?
mysql_* functions are deprecated. USe mysqli_*
Your code should look like this:
$q = mysqli_prepare($connection, 'INSERT INTO login (username, password, type) VALUES (?, ?, ?)';
mysqli_stmt_bind_param($q, 'sss', $m_nic, $f_name, $type);
mysqli_stmt_execute($q);

Insert into table with prepared statement

I'm trying to insert data from a form into a database using PHP and Mysqli but I can't get it working! My database has 4 fields: DATE, TITLE, CONTENT, ID. The ID field is auto-increment.
I've checked the connection and that's working fine. I've also echoed the form field values and the $blogDate variable I created, they're all fine too.
Here's my prepared statement:
if ($newBlog = $mysqli->prepare('INSERT INTO Blog VALUES ($blogDate, $_POST["bTitle"], $_POST["bContent"])')) {
$newBlog->execute();
$newBlog->close();
}
It's just not inserting the values into my table.
You are generating SQL containing strings that are not quoted or escaped.
Don't insert the data directly into the SQL string, use placeholders (?) and then bind the parameters before executing.
$query = "INSERT INTO Blog VALUES (?, ?, ?)";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("sss", $blogDate, $_POST["bTitle"], $_POST["bContent"]);
$stmt->execute();
Since you are aware about prepared statement:
$newBlog = $mysqli->prepare('INSERT INTO Blog (`dateCol`, `titleCol`, `contentCol`) VALUES (?, ?, ?)');
$newBlog->bind_param( 'sss', $blogDate, $_POST["bTitle"], $_POST["bContent"] );
$newBlog->execute();
$newBlog->close();
since you are using auto increment field you need to specify column name and then values
try this code
$query = "INSERT INTO Blog (colname_1,colname_2,colname_3) VALUES (?, ?, ?)";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("sss", $blogDate, $_POST["bTitle"], $_POST["bContent"]);
$stmt->execute();

If I use $_POST value directly in bindParam (mysqli) will there be a security issue?

I have been reading about using $_POST values being used directly in isert statements and understand that this is an invitation for trouble. What is not clear in any of the posts I read was -
Say my form is sending 7 items to my mysqli insertion script and I use the posted values like this:
$stmt = $mysqli->prepare("INSERT INTO `advertisements` (`from`, `r_u_res`, `email`, `blockname`, `floorno`, `doorno`, `content`) VALUES (?, ?, ?, ?, ?,?,?)");
$stmt->bind_param('sssssss', $_POST['from'], $_POST['rures'], $_POST['email'], $_POST['blockname'], $_POST['floorno'], $_POST['doorno'], $_POST['content']);
$stmt->execute();
$stmt->close();
Would that be the correct way to do it? Or should I first store the posted values in a new variable and use that variable while binding? - like this :
$postedfrom = $_POST['from'];
$postedrures = $_POST['rures'];
$postedemail = $_POST['email'];
$postedblockname = $_POST['blockname'];
$postedfloorno = $_POST['floorno'];
$posteddoorno = $_POST['doorno'];
$postedcontent = $_POST['content'];
$stmt = $mysqli->prepare("INSERT INTO `advertisements` (`from`, `r_u_res`, `email`, `blockname`, `floorno`, `doorno`, `content`) VALUES (?, ?, ?, ?, ?,?,?)");
$stmt->bind_param('sssssss', $postedfrom, $postedrures, $postedemail, $postedblockname, $postedfloorno, $posteddoorno, $postedcontent);
$stmt->execute();
$stmt->close();
I saw a post OO mysqli prepared statements help please where the answer does seem to be like the code above but I want to know whether doing it like the first code poses security issues...
both forms are equivalent from a security perspective as php first resolves the values to be passed in the method call to $stmt->bind_param, thus that function sees the exact same values in both cases.
ps: both snippets look ok to me.

Categories