Why mysqli executed prepared statement is not saving? - php

I've just learning to use prepared statement in mysqli & php. Here's the snippet of the code in question.
$stmt = $mysqli->prepare ("UPDATE courses set id=?, title=?, description=?, videourl=?, article=?, colcount=?, questiondisplayed=?, onfield=? WHERE id = ?");
if ($stmt == false) { die ('prepare() failed: ' . htmlspecialchars($mysqli->error)); }
$res = $stmt->bind_param("sssssiiis", $id, $title, $description2, $videourl, $article2, $colcount, $questiondisplayed, $onfield, $oldid);
if ($res == false) { die ('bind_param() failed: ' . htmlspecialchars($mysqli->error)); }
$res = $stmt->execute();
if ($res == false) die ('execute() failed: ' . htmlspecialchars($mysqli->error));
The problem is, even after these codes run successfully (the die function never gets called), the database is not updated at all. But it's updated successfully if I'm not using prepared statement (construct the SQL query string manually). I want to convert from using manually constructed SQL query string into prepared statement. But I'm stuck in this area. Btw, the variables supplied in bind param have been set right before these codes run. I've run a print_r ($_POST); and it shows that my POST values are contain the right data. Where's the problem? Thanks.

Related

fetching the data when using prepared statements with mysqli

This is the standard code I found online that etching the data when using prepared statements with mysqli:
$sql = "SELECT Title, CopyrightYear FROM Books WHERE ID=?";
if ($statement = mysqli_prepare($connection, $sql)) {
mysqli_stmt_bindm($statement, 'i', $id);
mysqli_stmt_execute($statement); //Question 1
mysqli_stmt_bind_result($statement, $title, $year);
while (mysqli_stmt_fetch($statement)) { //Question 2
echo $title . '-' . $year . '<br/>';
}
}
I have some questions:
why we don't store the result of mysqli_stmt_execute? we can use something like:
$result = mysqli_stmt_execute($statement); then we can retrieve each record from the result set?
Since we have already executed the query, what does mysqli_stmt_fetch($statement) mean? don't we have executed the $statement already, shouldn't it be like this : mysqli_stmt_fetch($result)?
The execute function doesn't return a result, but mysqli_stmt_get_result() does. Then you can fetch one row at a time from the result resource. This usage might make more sense to you:
if ($statement = mysqli_prepare($connection, $sql)) {
mysqli_stmt_bind_param($statement, 'i', $id);
mysqli_stmt_execute($statement);
$result = mysqli_stmt_get_result($statement);
while ($row = mysqli_fetch_assoc($result)) {
echo $row['title'] . '-' . $row['year'] . '<br/>';
}
}
One reason no result set is not returned from the execute function is that some SQL statements (like INSERT, UPDATE, DELETE, CREATE, DROP, etc.) have no result set. So the execute function only returns a boolean to indicate whether the statement ran successfully or not.
why we don't store the result of mysqli_stmt_execute? we can use something like: $result = mysqli_stmt_execute($statement); then we can retrieve each record from the result set?
That's because mysqli_stmt_execute() function only executes a query that has been prepared using the mysqli_prepare() function. When executed any parameter markers which exist will automatically be replaced with the appropriate data. It doesn't return any result set, rather it just returns the status of the execute query i.e. either TRUE or FALSE.
Since we have already executed the query, what does mysqli_stmt_fetch($statement) mean? don't we have executed the $statement already, shouldn't it be like this : mysqli_stmt_fetch($result)?
Again, since mysqli_stmt_fetch() function just executes the prepared statement and doesn't return any result set, you need to bind the variables to the prepared statement for storing the result. And from the doc,
When mysqli_stmt_fetch() is called to fetch data, the MySQL client/server protocol places the data for the bound columns into the specified variables var1, ....

Do I need to bind result when fetching all results for security?

When I was learning about SQL security and preventing SQL injection, I learnt that its better to use bindparam when fetching results for an id like this:
//Prepare Statement
$stmt = $mysqli->prepare("SELECT * FROM my_table WHERE id=?");
if ( false===$stmt ) {
die('prepare() failed: ' . htmlspecialchars($mysqli->error));
}
$rc = $stmt->bind_param("i", $id);
if ( false===$rc ) {
die('bind_param() failed: ' . htmlspecialchars($stmt->error));
}
$rc = $stmt->execute();
if ( false===$rc ) {
die('execute() failed: ' . htmlspecialchars($stmt->error));
}
// Get the data result from the query. You need to bind results for each column that is called in the prepare statement above
$stmt->bind_result($col1, $col2, $col3, $col4);
/* fetch values and store them to each variables */
while ($stmt->fetch()) {
$id = $col1;
$abc = $col2;
$def = $col3;
$xyz = $col4;
}
$stmt->close();
$mysqli->close();
Atm, when I am fetching all results, I am using this:
$query= "SELECT * FROM my_table";
$result=mysqli_query($connect, $query);
if (!$result)
{
die('Error fetching results: ' . mysqli_error());
exit();
}
echo '<table border="1">'; // start a table tag in the HTML
//Storing the results in an Array
while ($row = mysqli_fetch_array($result)) //Creates a loop to loop through results
{
echo "<tr><td>" . $row['abc'] . "</td><td>" . $row['def'] . "</td><td>" . $row['xyz'] . "</td></tr>";
}
echo '</table>'; //Close the table in HTML
My question is:
For my second code, do I need to use bind_result when fetching all results for any security reasons similar to my first example?
If yes, how can I use prepare statement with bind_result when I am fetching all results and not using $id?
If I use the second example the way it is for fetching all results, are there any security issues?
1) For my second code, do I need to use bind_result when fetching all results for any security reasons similar to my first example?
No. bind_result() has nothing to do with security. You can use whatever method you wish with any query.
2) If yes, how can I use prepare statement with bind_result when I am fetching all results and not using $id?
Exactly the same way as with any other query. There is no difference actually. and having any particular variable doesn't matter at all.
3) If I use the second example the way it is for fetching all results, are there any security issues?
There is always a security issue. But none from the area of SQL injection in this snippet. You may wish to check for XSS issues.
Just to clarify your ambiguous question:
In case you are confusing bind_result with bind_param, here is a rule of thumb: you have to use a placeholder (and thus bind_param()) for the every variable that is going into query. Always. No exceptions.
From this rule you can simply tell if you need to use prepare() or not in any particular case.
Also, there is no need for such a long and windy code in the first example.
$stmt = $mysqli->prepare("SELECT * FROM my_table WHERE id=?");
$rc = $stmt->bind_param("i", $id);
$rc = $stmt->execute();
$stmt->bind_result($id, $abc, $def, $xyz);
while ($stmt->fetch()) {
echo $id;
}
Just set mysqli in exception mode before connect:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

PHP SQL Prepared Statement: Fatal Error Call To Member Function

I've been trying to get prepared statements working - however, I keep running into the following error
<b>Fatal error</b>: Call to a member function bindParam() on a non-object on line <b>41</b><br />
I have copied exactly many tutorials and even the provided code did not work and threw the same error.
My code is below:
$mysqli = new mysqli(connect, username,pass, datatbase);
$name = 'Tester';
if (mysqli_connect_errno()) {
echo "Can't connect to MySQL Server. Errorcode: %s\n", mysqli_connect_error();
}
$stmt = $mysqli->prepare("INSERT INTO Parks VALUES (null,?,?,?,?,?,?,?,?,?,?,?,?,?,Now(),?,?,?, 0, 0, 0)");
if ($stmt === FALSE) {
die ("Mysql Error: " . $mysqli->error);
}
$stmt->bind_param('ssssssssssssssss', $name, $theme, $size, $mountains, $hills, $river, $lake, $island, $setofislands, $ocean, $waterfalls, $file, $image, $description, $author,$cs);
$stmt->execute();
$stmt->close();
$mysqli->close();
It's the BindParam Line causing the error.
thanks in advance :)
EDIT: Error resolved, however, no data is being inserted into the database.
EDIT: Updated query, database contains VARCHARs except for Description which is LONGTEXT. The final 3 are ints/doubles and there is a current date field.
bindParam is the PDO function. You are using mysqli so try bind_param instead. Where you have 'name' should also be the type definition, so you need 's' for string.
E.g:
$stmt->bind_param('s', $name);
Edit: Although saying that, the error doesn't say the function is incorrect. It says the object doesn't exist... Running this could would give you information as to why the prepare is failing.
$stmt = $mysqli->prepare("INSERT INTO 'Parks' VALUES(null, ?");
if ($stmt === FALSE) {
die ("Mysql Error: " . $mysqli->error);
}
Most likely the prepare is failing as the SQL is incorrect (My guess is the table name 'Parks' should NOT be in qutoes)
Edit 2: My guess for it still not working is:
$stmt->bindParam('name', $name);
Where you have 'name' should actually be the variable type, as in integer, double, string, etc. This is so the database knows what your variable is.
Try replacing that line with:
$stmt->bindParam('s', $name);

Verifying MYSQL executed a result not using get_result()

What's the best way to verify mysql executed successfully and then returned a result when you CANNOT use the following code:
$db = dbConnect();
//begin prepared statements to search db
$stmt = $db->prepare("SELECT email,authentication,email_confirm,externalid,password,id, admin FROM users WHERE email=?");
$stmt->bind_param('s',$email);
$stmt->execute();
$result = $stmt->get_result();
if (!$result){
//error statement
} if (!(mysqli_num_rows($result)==0)){
//action to perform
} else {
// no result returned
}
I was using get_result numerous times in my scripts, and my hosting provider doesn't have mysqlnd driver so I have to rewrite a lot of code. I know I am limited to bind_result and fetch(), but I need a little help rewriting the code since my mindset is stuck in the way I first did it.
I'm also using mysqli and not PDO.
The Mysqli fetch() function will return one of 3 values:
TRUE - Success. Data has been fetched
FALSE - Error occurred
NULL - No more rows/data exists or data truncation occurred
This means you can set your query like this:
$db = dbConnect();
$query = "SELECT email,authentication,email_confirm,externalid,password,id, admin FROM users WHERE email=?";
$stmt = $db->prepare();
$stmt->bind_param('s',$email);
$stmt->execute();
$stmt->bind_result($email,$auth,$email_confirm,$externalid,$password,$id,$admin);
// Will only execute loop if returns true
$record_count = 0;
while($result = $stmt->fetch())
{
// Increment counter
$record_count++;
// Do something with bound result variables
echo("Email is $email");
}
// After the loop we either ran out of results or had an error
if($result === FALSE)
{
echo("An error occurred: " . $db->error());
}
elseif($record_count == 0)
{
echo("No records exist.");
}

How to get all values out of the prepared statement query result

I have next code, to create mysqli object and to prepare query:
$GLOBALS['DB_something'] = new mysqli('$database_hostname','$database_username','$database_password','$database_default');
$GLOBALS['DB_prepared_get'] = $GLOBALS['DB_something']->prepare("SELECT ? from database_name WHERE hash=?");
and next code, to get and display the results. Since I haven't been into prepared statements recently, specialy not with PHP, im not sure how to get the results out of it.
When i wrote the code without prepared statements, it works, but for many reasons, I need to rewrite it with prepared statements.
$GLOBALS['DB_prepared_get']->bind_param('ss', $arg, $index);
$GLOBALS['DB_prepared_get']->execute();
$GLOBALS['DB_prepared_get']->bind_result($result); # this is an array of values
$GLOBALS['DB_prepared_get']->fetch();
# below this, I don't know if it's ok
if(mysql_num_rows($result) == 0){
return "0";
}
else{
while($GLOBALS['DB_prepared_get']->fetch()) {
return $result;
}
}
$GLOBALS['DB_prepared_get']->close();
Thanks for any help.
EDIT: just to be clear, my problem is how to fetch the exact result values to print them out or something. So syntax is what I am probably doing wrong.
As far as I know you can't specify the columns of a query as a parameter. You would have to write the columns directly in the prepared statement string.
Something like
$GLOBALS['DB_prepared_get'] = $GLOBALS['DB_something']->prepare("SELECT a,b,c from database_name WHERE hash=?");
There are so many faults in your code that I not even try to explain whats wrong with it. I can say however, that if you are not experienced in OO programming, you first should try to write the procedural code with mysqli.
This code should work:
$mysqli = new mysqli( $database_hostname, $database_username, $database_password, $database_default );
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
if ($stmt = $mysqli->prepare("SELECT ? from database_name WHERE hash=?")) {
$stmt->bind_param("s", $fieldname); // first marker
$stmt->bind_param("s", $hashwhere); // second marker
$stmt->execute();
$result = array();
while ($stmt->fetch()) {
$result[] = array($fieldname);
}
$stmt->close();
}
$mysqli->close();
var_dump($result);

Categories