Prepare of prepared statement failing with a select query - php

I have the following prepared statement that is failing in the prepared part. The database table is correct, as are the table columns. I have a similar prepared statement above this that works just fine. Does anyone see what is wrong in my prepare? 
 
$stmt2 = $con->prepare("SELECT * FROM forum_posts WHERE `category_id`=? AND `topic_id`=?");
if ( !$stmt2 || $con->error ) {
die('Select forum posts prepare() failed: ' . htmlspecialchars($con->error));
}
if(!$stmt2->bind_param('ii', $cid, $tid)) {
die('Select forum posts bind_param() failed: ' . htmlspecialchars($stmt2->error));
}
if(!$stmt2->execute()) {
die('Select forum posts execute() failed: ' . htmlspecialchars($stmt2->error));
}
Updated:
Error message - Select forum posts prepare() failed:
Full code as requested:
Using Chris Brand's answer - it gets me to the bind param and stops there...
<?php
$con = mysqli_connect("localhost", "root", "", "db");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$cid = $_GET['cid'];
$tid = $_GET['tid'];
$userid = ( isset( $_SESSION['user'] ) ? $_SESSION['user'] : "" );
//Prepared SELECT stmt to get forum topics
$stmt = $con->prepare("SELECT * FROM forum_topics WHERE `category_id`=? AND id=? LIMIT 1");
if (!$stmt || $con->error ) {
die('Select topics prepare() failed: ' . htmlspecialchars($con->error));
}
if(!$stmt->bind_param('ii', $cid, $tid)) {
die('Select topics bind_param() failed: ' . htmlspecialchars($stmt->error));
}
if(!$stmt->execute()) {
die('Select topics execute() failed: ' . htmlspecialchars($stmt->error));
}
$stmt->store_result();
$numrows = $stmt->num_rows;
if($numrows == 1){
echo "<table width='100%'>";
if ( $_SESSION['user'] ) {
echo "<tr><td colspan='2'><input type='submit' value='Add Reply' onClick=\"window.location =
'forum_post_reply.php?cid=".$cid."$tid=".$tid."'\"> <hr />";
} else {
echo "<tr><td colspan='2'><p>Please log in to add your reply</p><hr /></td></tr>";
}
foreach($stmt as $row) {
//Prepared SELECT stmt to get forum posts
if($stmt2 = $con->prepare("SELECT * FROM forum_posts WHERE `category_id`=? AND `topic_id`=?")) {
//var_dump($stmt2);
if (!$stmt2) {
die('Select forum posts prepare() failed: ' . htmlspecialchars($con->error));
}
} else {
var_dump($con->error);
}
if(!$stmt2->bind_param('ii', $cid, $tid)) {
die('Select forum posts bind_param() failed: ' . htmlspecialchars($stmt2->error));
}
if(!$stmt2->execute()) {
die('Select forum posts execute() failed: ' . htmlspecialchars($stmt2->error));
}
//while($row2 = mysqli_fetch_assoc($stmt2)){
foreach($stmt2 as $row2) {
echo "<tr><td valign='top' style='border: 1px solid #000000;'>
<div style='min-height: 125px;'>".$row['topic_title']."<br />
by ".$row2['post_creator']." - " .$row2['post_date']. "<hr />" . $row2['post_content'] ."</div></td>
<td width='200' valign='top' align='center' style='border: 1px solid #000000;'>User Info Here!</td></tr>
<tr><td colspan='2'><hr /></td></tr>";
}
}
} else {
echo "<p>This topic does not exist.</p>";
}
Using Abdulla's answer:
$con = mysqli_connect("localhost", "root", "", "db");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$cid = $_GET['cid'];
$tid = $_GET['tid'];
$userid = ( isset( $_SESSION['user'] ) ? $_SESSION['user'] : "" );
//Prepared SELECT stmt to get forum topics
$stmt = $con->prepare("SELECT * FROM forum_topics WHERE `category_id`=? AND id=? LIMIT 1");
if (!$stmt || $con->error ) {
die('Select topics prepare() failed: ' . htmlspecialchars($con->error));
}
if(!$stmt->bind_param('ii', $cid, $tid)) {
die('Select topics bind_param() failed: ' . htmlspecialchars($stmt->error));
}
if(!$stmt->execute()) {
die('Select topics execute() failed: ' . htmlspecialchars($stmt->error));
}
$stmt->store_result();
$numrows = $stmt->num_rows;
if($numrows == 1){
echo "<table width='100%'>";
if ( $_SESSION['user'] ) {
echo "<tr><td colspan='2'><input type='submit' value='Add Reply' onClick=\"window.location =
'forum_post_reply.php?cid=".$cid."$tid=".$tid."'\"> <hr />";
} else {
echo "<tr><td colspan='2'><p>Please log in to add your reply</p><hr /></td></tr>";
}
foreach($stmt as $row) {
//Prepared SELECT stmt to get forum posts
$stmt2 = $mysqli::prepare("SELECT * FROM forum_posts WHERE category_id='value' AND topic_id='value'");
//var_dump($stmt2);
//if ( !$stmt2 || $con->error ) {
//die('Select forum posts prepare() failed: ' . htmlspecialchars($con->error));
// }
//var_dump($con->error);
if(!mysqli_stmt_bind_param($stmt2,"i", $cid, $tid)) //i means intiger
{
die('Select forum posts bind_param() failed: ' . htmlspecialchars($stmt2->error));
}
if(!mysqli_stmt_execute($stmt2)) {
die('Select forum posts execute() failed: ' . htmlspecialchars($stmt2->error));
}
//while($row2 = mysqli_fetch_assoc($stmt2)){
foreach($stmt2 as $row2) {
echo "<tr><td valign='top' style='border: 1px solid #000000;'>
<div style='min-height: 125px;'>".$row['topic_title']."<br />
by ".$row2['post_creator']." - " .$row2['post_date']. "<hr />" . $row2['post_content'] ."</div></td>
<td width='200' valign='top' align='center' style='border: 1px solid #000000;'>User Info Here!</td></tr>
<tr><td colspan='2'><hr /></td></tr>";
}
}
} else {
echo "<p>This topic does not exist.</p>";
}

Prepared Statements fail for a few reasons:
1) Database is not connected.
2) Query is not correctly being built
/* First check the correction */
if ( mysqli_connect_errno() ) {
printf("Connect failed: %s\n", mysqli_connect_error());
}
/* Secondly try to print out the query after this statement*/
$stmt2 = $con->prepare("SELECT * FROM forum_posts WHERE `category_id`=? AND `topic_id`=?");
var_dump($stmt2);
My Guess is that $stmt2 is returning FALSE

use this
$stmt2 = $mysqli->prepare("SELECT * FROM forum_posts WHERE category_id='value' AND topic_id='value'")
//check connection error
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
//Bind parameter values
read this table
if(!mysqli_stmt_bind_param($stmt2,"i", $cid, $tid)) //i means intiger
{
die('Select forum posts bind_param() failed: ' . htmlspecialchars($stmt2->error));
}
if(!mysqli_stmt_execute($stmt2))
{
die('Select forum posts execute() failed: ' . htmlspecialchars($stmt2->error));
}

$con->error is a string and it may be causing your if statement to evaluate to true.
try something like:
$con->free();
if (!$stmt2 || !empty($con->error))
or
$con->free();
if ($stmt2 = $con->prepare(...))
{
...
}
else
{
var_dump($con->error);
}
If your statement object is populated (as indicated in the other answer), it has to be the $con->error variable that evaluates to true
Update:
You should try and release the previous statement using http://php.net/manual/ru/mysqli-result.free.php or http://www.php.net/manual/ru/mysqli-stmt.close.php.

Related

Fatal error: Uncaught Error: Call to undefined function mysqli_stmt_get_result()

I'm dealing with a fatal error, and I see a lot of solutions for it everywhere but I can't seem to find the right solution that fits in my code...
so this is the code where it goes wrong:
$link = mysqli_connect($server, $gebruiker, $wachtwoord, $database);
if($link === false) {
die("ERROR: Kon geen verbinding maken. " . mysqli_connect_error());
}
if(isset($_REQUEST['term'])) {
$sql = "SELECT * FROM producten WHERE naam LIKE ?";
if($stmt = mysqli_prepare($link, $sql)) {
mysqli_stmt_bind_param($stmt, "s", $param_term);
$param_term = '%' . $_REQUEST['term'] . '%';
if(mysqli_stmt_execute($stmt)) {
$result = mysqli_stmt_get_result($stmt);
if(mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
echo "<p>" . $row["naam"] . "</p>";
}
} else {
echo "<p>Geen producten gevonden</p>";
}
} else {
echo "ERROR: Kon $sql niet uitvoeren. " . mysqli_error($link);
}
}
mysqli_stmt_close($stmt);
}
mysqli_close($link);
this is the part that messes it all up:
$result = mysqli_stmt_get_result($stmt);
Who can help me in the right direction, thanks!
I fixed it, the solution:
if(isset($_REQUEST['term'])) {
$conn = mysqli_connect($server, $gebruiker, $wachtwoord, $database); //Connection to my database
$query = "SELECT id, naam FROM producten WHERE naam LIKE ?";
$statement = $conn->prepare($query);
$term = "%".$_REQUEST['term']."%";
$statement->bind_param("s", $term);
$statement->execute();
$statement->store_result();
if($statement->num_rows() == 0) {
echo "<p>Geen producten gevonden ".$_REQUEST['term']."</p>";
$statement->close();
$conn->close();
} else {
$statement->bind_result($id,$naam);
while ($statement->fetch()) {
echo "<p>" . $naam . "</p>";
};
$statement->close();
$conn->close();
};};

PHP selecting from a MYSql view Returns Nothing

This is odd and I just can't seem to find what is wrong.
Here is a simple example:
In my PHP code, I can select from a table and have results returned.
But, If I change my SQL statement to select from a view, no results are returned.
This Code Returns results:
$link = mysqli_connect(HOST, USER, PASSWORD, DATABASE);
$sql_stmt_bind = "Select fk_member_id as ID FROM member_role LIMIT 1";
$stmt = $link->stmt_init();
$stmt->prepare($sql_stmt_bind);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($mem_id);
$stmt->fetch();
echo '<br>';
echo 'rows: ' . $stmt->num_rows;
echo '<br>';
//echo 'lastname: ' . $lastname;
echo 'ID: ' . $mem_id;
echo '<br>';
The Results:
rows: 1
ID: 1
This Code Returns unexpected results:
$link = mysqli_connect(HOST, USER, PASSWORD, DATABASE);
$sql_stmt_bind = "Select fk_member_id as ID FROM vw_test LIMIT 1";
$stmt = $link->stmt_init();
$stmt->prepare($sql_stmt_bind);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($mem_id);
$stmt->fetch();
echo '<br>';
echo 'rows: ' . $stmt->num_rows;
echo '<br>';
//echo 'lastname: ' . $lastname;
echo 'ID: ' . $mem_id;
echo '<br>';
The Results:
rows: 0
ID: 0
This is the Create statement for the View:
Create or replace View vw_test
as
Select fk_member_id FROM member_role
;
So I'm at a total loss.
I've been running the same code for the past 4 or 5 years with no issues.
(This is for a community sports association and runs for only a few months of the year.)
I was double checking the code before I turned on the web pages again...and now all of my code accessing views no longer works.
Please help! thanks.
UPDATE
I'm now using this code segment:
$stmt = $link->stmt_init();
$pre = $stmt->prepare($sql_stmt_bind);
if ( false===$pre ) {
die('prepare() failed: ' . htmlspecialchars($stmt->error));
}
$exe = $stmt->execute();
if ( false===$exe ) {
die('execute() failed: ' . htmlspecialchars($stmt->error));
}
$stmt->store_result();
$bind_r = $stmt->bind_result($mem_id);
if ( false===$bind_r ) {
die('bind_result() failed: ' . htmlspecialchars($stmt->error));
}
$stmt->fetch();
The error I now receive is:
execute() failed: Prepared statement needs to be re-prepared
Any Ideas? Thanks.
Try to check your code to know where the problem is.
Try this:
$link = mysqli_connect(HOST, USER, PASSWORD, DATABASE);
$sql_stmt_bind = "Select fk_member_id as ID FROM vw_test LIMIT 1";
$stmt = $link->stmt_init();
$pre = $stmt->prepare($sql_stmt_bind);
if ( false===$pre ) {
die('prepare() failed: ' . htmlspecialchars($stmt->error));
}
$exe = $stmt->execute();
if ( false===$exe ) {
die('execute() failed: ' . htmlspecialchars($stmt->error));
}
$stmt->store_result();
$bind_r = $stmt->bind_result($mem_id);
if ( false===$bind_r ) {
die('bind_result() failed: ' . htmlspecialchars($stmt->error));
}
$stmt->fetch();
echo '<br>';
echo 'rows: ' . $stmt->num_rows;
echo '<br>';
//echo 'lastname: ' . $lastname;
echo 'ID: ' . $mem_id;
echo '<br>';
EDIT
Work around for the problem(failed: Prepared statement needs to be re-prepared)
- using the PDO adapter instead of Mysql adapter
- Add this Attribute to your connection string $link->setAttribute( PDO::ATTR_EMULATE_PREPARES, true);

Foreach and while loop not outputting my fetched data

I have the following two prepared statements. The db connection and queries are correct, I have tested them within phpmyadmin. I also tested inside of my while fetch loop to see if I am pulling the data I am supposed to be and I am.
The problem resides in my while and foreach loops or possibly my num rows statement. I am not sure what I am doing incorrectly in there.
I am getting this error:
Warning: mysqli::query() expects parameter 1 to be string, object given
For this while loop:
while ($row2 = $result->fetch_assoc() ) {
I am also getting my else statement..
echo "<p>This topic does not exist.</p>";
Even though the info is echoing out correctly, again I just think my loops are wrong?
Does anyone see what I am doing wrong in my loops?
$con = new mysqli("localhost", "", "", "");
if (mysqli_connect_errno()) {
throw new Exception("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* activate reporting */
$driver = new mysqli_driver();
try {
$cid = $_GET['cid'];
$tid = $_GET['tid'];
$userid = ( isset( $_SESSION['user'] ) ? $_SESSION['user'] : "" );
echo $cid . "<br>";
echo $tid;
//Prepare
if ($stmt = $con->prepare("SELECT * FROM forum_topics WHERE `category_id`=? AND `id`=? LIMIT 1")) {
$stmt->bind_param("ii", $cid, $tid);
$stmt->execute();
$stmt->bind_result($topic_id, $category_id, $topic_title, $topic_creator, $topic_last_user, $topic_date, $topic_reply_date, $topic_views);
if (!$stmt) {
throw new Exception($con->error);
}
}
while ($row = $stmt->fetch()) {
$stmt->store_result();
$numrows = $stmt->num_rows;
echo $numrows;
}
if($numrows == 1){
echo "<table width='100%'>";
if ( $_SESSION['user'] ) {
echo "<tr><td colspan='2'><input type='submit' value='Add Reply' onclick=\"window.location =
'forum_post_reply.php?cid=".$cid."$tid=".$tid."'\"> <hr />";
} else {
echo "<tr><td colspan='2'><p>Please log in to add your reply</p><hr /></td></tr>";
}
}
foreach($stmt as $row) {
//Prepared SELECT stmt to get forum posts
if($stmt2 = $con->prepare("SELECT `id`, `category_id`, `topic_id`, `post_creator`, `post_content`, `post_date` FROM forum_posts WHERE `category_id`=? AND `topic_id`=?")) {
$stmt2->bind_param("ii", $cid, $tid);
$stmt2->execute();
$stmt2->bind_result($post_id, $post_category_id, $post_topic_id, $post_creator, $post_content, $post_date);
if (!$stmt2) {
throw new Exception($con->error);
}
}
}
if ($result = $con->query($stmt)) {
while ($row2 = $result->fetch_assoc() ) {
echo "<tr><td valign='top' style='border: 1px solid #000000;'>
<div style='min-height: 125px;'>".$row['topic_title']."<br />
by ".$row2['post_creator']." - " .$row2['post_date']. "<hr />" . $row2['post_content'] ."</div></td>
<td width='200' valign='top' align='center' style='border: 1px solid #000000;'>User Info Here!</td></tr>
<tr><td colspan='2'><hr /></td></tr>";
}
} else {
echo "<p>This topic does not exist.</p>";
}
}
catch (Exception $e)
{
echo "Error: " . $e->getMessage();
}
if you search on $stmt with ctrl-F in your browser (and ignoring $stmt2), you will notice that $stmt is a prepared statement all the way down to the error line. $stmt comes to life as a return type from prepare, is bound, and executed.
later on you:
if ($result = $con->query($stmt)) {
so $con->query() is expecting a string, not an object, no?
From the manual.
Not that there aren't other things to consider under a microscope, but I hope this narrowly answers the error message for you.
Edit:
Apparently, you cannot use bind_result with select *. Read the gents Accepted Answer to this question. He does 2 examples, 1 with 1 without select *. Also note store_result()
Here is the link to his answer that was upvoted quite a bit.

Database output not showing. Getting else statement

I have the following code that I am not getting any of my db output to appear on my site. I only get the else statement echo response of echo "<p>This topic does not exist.</p>";, but I have topics in my database.
Does anyone see anything in my code that would cause this to not display any output and make the else statement appear? If there isn't, how can I debug this to figure out the issue? I am not getting any errors from my prepared statements, so it has to be within the numrows statement or while loop.
$con = mysqli_connect("localhost", "root", "", "db");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$cid = $_GET['cid'];
$tid = $_GET['tid'];
$userid = ( isset( $_SESSION['user'] ) ? $_SESSION['user'] : "" );
//Prepared SELECT stmt to get forum topics
$stmt = $con->prepare("SELECT * FROM forum_topics WHERE `category_id`=? AND id=? LIMIT 1");
if ( !$stmt || $con->error ) {
die('Select topics prepare() failed: ' . htmlspecialchars($con->error));
}
if(!$stmt->bind_param('ii', $cid, $tid)) {
die('Select topics bind_param() failed: ' . htmlspecialchars($stmt->error));
}
if(!$stmt->execute()) {
die('Select topics execute() failed: ' . htmlspecialchars($stmt->error));
}
$numrows = $stmt->num_rows;
if($numrows == 1){
echo "<table width='100%'>";
if ( $_SESSION['user'] ) {
echo "<tr><td colspan='2'><input type='submit' value='Add Reply' onClick=\"window.location =
'forum_post_reply.php?cid=".$cid."$tid=".$tid."'\"> <hr />";
} else {
echo "<tr><td colspan='2'><p>Please log in to add your reply</p><hr /></td></tr>";
}
while($row = mysqli_fetch_assoc($stmt)){
//Prepared SELECT stmt to get forum topics
$stmt2 = $con->prepare("SELECT * FROM forum_posts WHERE `category_id`=? AND topic_id=?");
if ( !$stmt2 || $con->error ) {
die('Select topics prepare() failed: ' . htmlspecialchars($con->error));
}
if(!$stmt2->bind_param('ii', $cid, $tid)) {
die('Select topics bind_param() failed: ' . htmlspecialchars($stmt2->error));
}
if(!$stmt2->execute()) {
die('Select topics execute() failed: ' . htmlspecialchars($stmt2->error));
}
while($row2 = mysqli_fetch_assoc($stmt2)){
echo "<tr><td valign='top' style='border: 1px solid #000000;'>
<div style='min-height: 125px;'>".$row['topic_title']."<br />
by ".$row2['post_creator']." - " .$row2['post_date']. "<hr />" . $row2['post_content'] ."</div></td>
<td width='200' valign='top' align='center' style='border: 1px solid #000000;'>User Info Here!</td></tr>
<tr><td colspan='2'><hr /></td></tr>";
}
}
} else {
echo "<p>This topic does not exist.</p>";
}
$cid = $_GET['cid']; is the category id
`$tid = $_GET['tid'];` is another id
To quote the documentation:
Returns the number of rows in the result set. The use of mysqli_stmt_num_rows() depends on whether or not you used mysqli_stmt_store_result() to buffer the entire result set in the statement handle.
The following should do the trick:
$stmt->store_result();
$numrows = $stmt->num_rows;
if ($numrows == 1) {
// etc...

Issue deleting rows from displayed table

So I have an issue getting rows to be deleted using the following code. The table displays the information correctly, plus sends the correct id in the url to the delete.php page, but I cannot get it to complete the command. Changing the code slightly on the delete.php I can get it to show either:
Couldn't delete the index.
or:
Binding parameters failed: 0
<?php
$con = mysqli_connect("localhost","user","pass","database");
// Check connection
if (mysqli_connect_errno())
{
die("Failed to connect to MySQL: " . mysqli_connect_error());
}
if (!$result = mysqli_query($con,"SELECT * FROM mytable ORDER BY `server_name`;"))
{
die("Error: " . mysqli_error($con));
}
?>
<table border='1'>
<tr>
<th><b>Server Name</b></th>
<th><center><b>Port</b></center></th>
<th><center><b>Mod</b></center></th>
</tr>
<?php
while($row = mysqli_fetch_array($result))
{
?>
<tr>
<td><?php echo $row['server_name']; ?></td>
<td><center><?php echo $row['server_port']; ?></center></td>
<td><center><?php echo $row['mod']; ?></center></td>
<td><center><img src="images/remove.png" width="16" height="16"></center></img></td>
</tr>
<?php
}
mysqli_close($con);
?>
</table>
My delete file is
<?php
// Your database info
$db_host = 'localhost';
$db_user = 'user';
$db_pass = 'pass';
$db_name = 'database';
if (!isset($_GET['id']))
{
echo 'No ID was given...';
exit;
}
$con = new mysqli($db_host, $db_user, $db_pass, $db_name);
if ($con->connect_error)
{
die('Connect Error (' . $con->connect_errno . ') ' . $con->connect_error);
}
$sql = "DELETE FROM mytable WHERE 'index' = " . $_GET['id'];
if (!$result = $con->prepare($sql))
{
die('Query failed: (' . $con->errno . ') ' . $con->error);
}
if (!$result->bind_param('i', $_GET['ID']))
{
die('Binding parameters failed: (' . $result->errno . ') ' . $result->error);
}
if (!$result->execute())
{
die('Execute failed: (' . $result->errno . ') ' . $result->error);
}
if ($result->affected_rows > 0)
{
echo "The ID was deleted with success.";
}
else
{
echo "Couldn't delete the index.";
}
$result->close();
$con->close();
It has to be something simple but I cannot figure it out.
You're using the wrong type of quotes in your SQL. To escape a table or column name that contains a reserved word, you use backticks. And if you're using bind_param, you have to put ? in the query where the parameter will be substituted.
$sql = "DELETE FROM mytable WHERE `index` = ?";
Replace the following line in your delete.php file:
$sql = "DELETE FROM mytable WHERE 'index' = " . $_GET['id'];
with:
$sql = "DELETE FROM mytable WHERE `index` = ?";
Changes in the suggested replacement statement include:
Replace single quotes around column name index with backticks. Note that MySQL escape character is a backtick not single quotes.
You are not including any parameter placeholders in your delete query but further down you are attempting to bind an integer parameter.

Categories