Prepared Statements - Number of Rows - php

I'm just trying to figure out how to determine the number of rows and then make that number display in the HTML.
My prepared statement looks like this:
if($stmt = $mysqli -> prepare("SELECT field1, field2, field3 FROM table WHERE id= ?ORDER BY id ASC"))
{
/* Bind parameters, s - string, b - blob, i - int, etc */
$stmt -> bind_param("i", $id);
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($testfield1, $testfield2, $testfield3);
/* Fetch the value */
$stmt -> fetch();
/* Close statement */
$stmt -> close();
}
I understand that I'm supposed to first save the results, then use num_rows, like this:
$stmt->store_result();
$stmt->num_rows;
However, I'm running, and issue with the page bugging out when I put that code in there. I haven't even been able to get to the next step of how to display the number of rows
What am I missing in terms of calculating the number of rows inside the prepared statement, then how would I display it with a <?php echo '# rows: '.$WHATGOESHERE;?>

num_rows returns the number, you have to store it in a variable.
/*.....other code...*/
$numberofrows = $stmt->num_rows;
/*.....other code...*/
echo '# rows: '.$numberofrows;
So full code should be something like this:
$stmt = $mysqli -> prepare("SELECT field1, field2, field3 FROM table WHERE id= ? ORDER BY id ASC");
/* Bind parameters, s - string, b - blob, i - int, etc */
$stmt -> bind_param("i", $id);
$stmt -> execute();
$stmt -> store_result();
/* Bind results */
$stmt -> bind_result($testfield1, $testfield2, $testfield3);
/* Fetch the value */
$stmt -> fetch();
$numberofrows = $stmt->num_rows;
/* Close statement */
$stmt -> close();
echo '# rows: '.$numberofrows;

If you are only interested in the row count instead of the actual rows of data, here is a complete query block with a COUNT(*) call in the SELECT clause.
$conn = new mysqli("host", "user", "pass", "db");
$stmt = $conn->prepare("SELECT COUNT(*) FROM `table` WHERE id= ?");
$stmt->bind_param("s", $id);
$stmt->execute();
$stmt->bind_result($num_rows);
$stmt->fetch();
echo $num_rows;
Or if you want to know the row count before iterating/processing the rows, one way is to lump the entire resultset (multi-dimensional array) into a variable and call count() before iterating.
$conn = new mysqli("host", "user", "pass", "db");
$sql = "SELECT field1, field2, field3
FROM table
WHERE id= ?
ORDER BY id";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $id);
$stmt->execute();
$result = $stmt->get_result();
$resultset = $result->fetch_all(MYSQLI_ASSOC);
echo "<div>Num: " , count($resultset) , "</div>";
foreach ($resultset as $row) {
echo "<div>Row: {$row['field1']} & {$row['field2']} & {$row['field3']}</div>";
}
*I have tested both of the above snippets to be successful on my localhost.

This works as of Feb 2020:
$number_of_records = $stmt->rowCount();
echo $number_of_records;
From php.net manual:
PDOStatement::rowCount() returns the number of rows affected by a
DELETE, INSERT, or UPDATE statement.
Here is an example from their website:
<?php
/* Delete all rows from the FRUIT table */
$del = $dbh->prepare('DELETE FROM fruit');
$del->execute();
/* Return number of rows that were deleted */
print("Return number of rows that were deleted:\n");
$count = $del->rowCount();
print("Deleted $count rows.\n");
?>
The above example will output:
Return number of rows that were deleted:
Deleted 9 rows.

Check out the example #2 here:
PHP.net
Use PDO::query() to issue a SELECT COUNT(*) statement with the same predicates as your intended SELECT statement, then use PDOStatement::fetchColumn() to retrieve the number of rows that will be returned. Your application can then perform the correct action.

Related

Nested prepared statements and free_result

Can someone explain why free_result after a while loop on a nested prepared statement causes bind_result to not update values as intended?
$stmt = $mysqli -> prepare("select col1 from table1 inner join ...");
$stmt -> bind_param("i", $id);
$stmt -> bind_result($col1);
$stmt -> execute() or die();
$stmt -> store_result();
$stmt2 = $mysqli -> prepare("select col2, col3 from table2 where col4 = ?");
$stmt2 -> bind_param("i", $col1);
$stmt2 -> bind_result($col2, $col3);
while ($stmt -> fetch()) {
$stmt2 -> execute() or die();
$stmt2 -> store_result();
while ($stmt2 -> fetch()) {
echo $col2 .",";
}
$stmt2 -> free_result(); // <== Works fine without this line
echo "---";
}
$stmt -> close();
$stmt2 -> close();
If I remove free_result, I get the expected output, let's say:
1,2,---3,4,5,---6,7,---
If I leave it, the last result of the first run on the parent loop repeats like so:
1,2,---2,2,2,---2,2,---
I can't find the answer in the docs ... It seems counter-intuitive since the results are retained instead of being freed.
Here's an executable example
As stated in the documentation for bind_result():
All columns must be bound after mysqli_stmt_execute() and prior to calling mysqli_stmt_fetch().
If you move the bind_result() call to the appropriate place it will work:
$stmt = $mysqli->prepare("select col1 from table1");
$stmt->execute();
$stmt->bind_result($col1);
$stmt->store_result();
$stmt2 = $mysqli->prepare("select col2, col3 from table2 where col4 = ?");
$stmt2->bind_param("i", $col1);
while ($stmt->fetch()) {
$stmt2->execute();
$stmt2->bind_result($col2, $col3);
$stmt2->store_result();
while ($stmt2->fetch()) {
echo $col2 .",";
}
$stmt2->free_result();
echo "---";
}
$stmt->close();
$stmt2->close();
The reason for this is that mysqli_stmt::free_result() asks mysqlnd to free up all result variables. The references are released, but neither the variables nor their values are not destroyed by PHP. They are just unbound.
You can either stop using mysqli_stmt::free_result() (which you probably should do anyway) or bind the result variables after every execution.

Get output of SQL query when using PHP

Following a tutorial, I execute SQL queries using PHP like so:
$query = $pdo -> prepare("SELECT id FROM Families WHERE family_name = ?");
$query -> bindValue(1, $family_name);
$query -> execute();
$query2 = $pdo -> prepare("SELECT * FROM Categories WHERE family_id = ?");
$query2 -> bindValue(1, $query); //ISSUE IN THIS LINE
$query2 -> execute();
My question: How do I take the result of the first query, the id, and put it as input in the second query?
You need to fetch the result, execute only runs the query in db, it does not get the values, try this which will return an array:
$result = $query->fetchAll();
If you know you only want one result, try:
$result = $query->fetch();
store the first query result in an object like
$result = $query->execute();
if ($result && $result->num_rows > 0)
{
$family = $Result->fetch_object();
$query2 = $pdo -> prepare("SELECT * FROM Categories WHERE family_id = ?");
$query2 -> bindValue(1, $family->id);
$query2 -> execute();
}
Please use limit 1 so that object don't return more than one id
$stmt1 = $pdo->prepare("SELECT id FROM Families WHERE family_name = ?");
$stmt1->bindValue(1, $family_name);
$stmt1->execute();
$family = $stmt1->fetch(PDO::FETCH_OBJ); //You can use fetch inorder to return 1 result for more use fetchAll();
//Here $family is now an object array
//Stored id in $family_id variable
$family_id = $family->family_id; //All the columns will save as properties now so you can easily access each of them
$stmt2 = $pdo->prepare("SELECT * FROM Categories WHERE family_id = ?");
$stmt2->bindValue(1, $family_id);
$stmt2->execute();
$stmt2->fetchAll(PDO::FETCH_OBJ); //Used fetchAll method because It's returning more than 1 result I guess
Try combining the Queries:
SELECT f.* FROM Families INNER JOIN Categories c on c.id = f.family_id WHERE c.family_name = ?
Fetch the result as Mohsen Nazari has stated

Can I redefine the same prepared statement?

I have a script that sends more than 10 queries of all CRUD types on 5 tables (some of the SELECTs with JOINs). Originally, I used mysqli_* functions for all those. Now, to improve security, I am porting the code to use prepared statements.
I have no previous experience using prepared statements and I have some doubts about what can and cannot be done. For instance lets say I start by a SELECT query, then have an UPDATE and finally an INSERT.
My question is this:
Should I repeat the mysqli_stmt_init and mysqli_stmt_close for each query, or could I initiate once before the first query, prepare a statement for each query and use it and finally close it after all queries are done with? In other words, is method 2 OK, or should I stick to method 1?
Method 1 - No reuse
// SELECT
$stmt = mysqli_stmt_init($link);
mysqli_stmt_prepare($stmt, "SELECT on table 1 and table 2");
...
mysqli_stmt_close($stmt);
// UPDATE
$stmt = mysqli_stmt_init($link);
mysqli_stmt_prepare($stmt, "UPDATE on table 3");
...
mysqli_stmt_close($stmt);
// INSERT
$stmt = mysqli_stmt_init($link);
mysqli_stmt_prepare($stmt, "INSERT INTO table 4");
...
mysqli_stmt_close($stmt);
Method 2 - Reusing statement
// INIT
$stmt = mysqli_stmt_init($link);
// SELECT
mysqli_stmt_prepare($stmt, "SELECT on table 1 and table 2");
...
// UPDATE
mysqli_stmt_prepare($stmt, "UPDATE on table 3");
...
// INSERT
mysqli_stmt_prepare($stmt, "INSERT INTO table 4");
...
// CLOSE
mysqli_stmt_close($stmt);
There is no need for stmt_init() or stmt_close(), mysqli_prepare() returns a stmt object and PHP handles the cleaning, the correct order is mysqli_stmt::prepare => mysqli_stmt::bind_param => mysqli_stmt::execute.
$mysqli = new mysqli( "host", "user", "pass", "db" );
$stmt = $mysqli->prepare( "SELECT * FROM table WHERE id = ?" );
$stmt->bind_param( "i", $id );
$id = 5;
$stmt->execute();
You can execute the same statement multiple times with different params, for example:
$stmt = $mysqli->prepare( "SELECT * FROM table WHERE id = ?" );
$stmt->bind_param( "i", $id );
$id = 5;
$stmt->execute(); // executed: SELECT * FROM table WHERE id = 5
$id = 3;
$stmt->execute(); // executed: SELECT * FROM table WHERE id = 3
But in case of different statements you must prepare each statement separately.
Yes, method 2 is ok.
There is no need to finally close it either, as it will be closed when your script ends.

Echo Mysqli query with POST variable?

want i want is to query my db with post variable in the query. It's not really working for me, does anyone know how to do it properly?
Here is what i have so far.
$query = "SELECT column FROM `table` WHERE 'name' = '$_POST[checkname]'";
$result = mysqli_query($db, $query) or die ("no query");
$cod = mysqli_fetch($result);
echo $cod;
Any help is appreciated. Thanks guys.
Mysqli supports prepared statements, which protect against sql injection attacks. It would look like this:
/* Create a prepared statement */
$stmt = $mysqli -> prepare("SELECT column FROM table WHERE name=?");
/* Bind parameters */
$stmt -> bind_param("s", $_POST['checkname']);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($result);
/* Fetch the value */
$stmt -> fetch();
echo $result;
Check the manual for more info.
A quick rundown, in response to the comment:
In $stmt->prepare("..."), you're forming your query, and you hold the place of any variables you intend to use with a "?"
In $stmt -> bind_param(...), you're binding the variables to their corresponding question mark. The first argument is the type, the following arguments are the variables. If you were using a string and an integer, inside the parenthesis it would look like "si", $stringVar, $intVar
In $stmt -> bind_result(...) you are stating what you are binding the results to. If the query was for a name and age, inside the parethesis would look like $name, age
In $stmt->fetch(), you're fetching the result. If it was multiple rows returned, you would do something like:
while($stmt->fetch()) {
//code here
}
Alternatively, you could use PDO. It would look something like this:
/* Create a prepared statement */
$stmt = $pdo->prepare("SELECT column FROM table WHERE name=:checkname");
/* Bind parameters */
$stmt->bindParam(':checkname', $_POST['checkname']);
/* Execute it */
$stmt->execute();
/* Fetch results */
$obj = $stmt->fetchObject();
echo $obj->column;
Check the manual for more info.
//it is apsulutly
// work
if(isset($_POST['checkname']))
{
$post = mysql_real_escape_string(trim($_POST[' checkname ']));
$query = "SELECT column FROM `table` WHERE name = '$post'";
$result = mysqli_query($db, $query) or die ("no query");
$cod = mysqli_fetch_all($result);
echo implode($cod[0]);
echo implode($cod[1]);//For particular cell
}
it works, just try it out like this
following your code...
if(isset($_POST['checkname']))
{
//to avoid SQL injections
$post = mysql_real_escape_string(trim($_POST['checkname']));
$query = "SELECT column FROM `table` WHERE name = '$post'";``
$result = mysqli_query($db, $query) or die ("no query");
$cod = mysqli_fetch($result);
echo $cod;
}

How can I properly use a PDO object for a parameterized SELECT query

I've tried following the PHP.net instructions for doing SELECT queries but I am not sure the best way to go about doing this.
I would like to use a parameterized SELECT query, if possible, to return the ID in a table where the name field matches the parameter. This should return one ID because it will be unique.
I would then like to use that ID for an INSERT into another table, so I will need to determine if it was successful or not.
I also read that you can prepare the queries for reuse but I wasn't sure how this helps.
You select data like this:
$db = new PDO("...");
$statement = $db->prepare("select id from some_table where name = :name");
$statement->execute(array(':name' => "Jimbo"));
$row = $statement->fetch(); // Use fetchAll() if you want all results, or just iterate over the statement, since it implements Iterator
You insert in the same way:
$statement = $db->prepare("insert into some_other_table (some_id) values (:some_id)");
$statement->execute(array(':some_id' => $row['id']));
I recommend that you configure PDO to throw exceptions upon error. You would then get a PDOException if any of the queries fail - No need to check explicitly. To turn on exceptions, call this just after you've created the $db object:
$db = new PDO("...");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
I've been working with PDO lately and the answer above is completely right, but I just wanted to document that the following works as well.
$nametosearch = "Tobias";
$conn = new PDO("server", "username", "password");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sth = $conn->prepare("SELECT `id` from `tablename` WHERE `name` = :name");
$sth->bindParam(':name', $nametosearch);
// Or sth->bindParam(':name', $_POST['namefromform']); depending on application
$sth->execute();
You can use the bindParam or bindValue methods to help prepare your statement.
It makes things more clear on first sight instead of doing $check->execute(array(':name' => $name)); Especially if you are binding multiple values/variables.
Check the clear, easy to read example below:
$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname LIMIT 1");
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname', 'Bloggs');
$q->execute();
if ($q->rowCount() > 0){
$check = $q->fetch(PDO::FETCH_ASSOC);
$row_id = $check['id'];
// do something
}
If you are expecting multiple rows remove the LIMIT 1 and change the fetch method into fetchAll:
$q = $db->prepare("SELECT id FROM table WHERE forename = :forename and surname = :surname");// removed limit 1
$q->bindValue(':forename', 'Joe');
$q->bindValue(':surname', 'Bloggs');
$q->execute();
if ($q->rowCount() > 0){
$check = $q->fetchAll(PDO::FETCH_ASSOC);
//$check will now hold an array of returned rows.
//let's say we need the second result, i.e. index of 1
$row_id = $check[1]['id'];
// do something
}
A litle bit complete answer is here with all ready for use:
$sql = "SELECT `username` FROM `users` WHERE `id` = :id";
$q = $dbh->prepare($sql);
$q->execute(array(':id' => "4"));
$done= $q->fetch();
echo $done[0];
Here $dbh is PDO db connecter, and based on id from table users we've get the username using fetch();
I hope this help someone, Enjoy!
Method 1:USE PDO query method
$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
Getting Row Count
$stmt = $db->query('SELECT id FROM Employee where name ="'.$name.'"');
$row_count = $stmt->rowCount();
echo $row_count.' rows selected';
Method 2: Statements With Parameters
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->execute(array($name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Method 3:Bind parameters
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=?");
$stmt->bindValue(1, $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
**bind with named parameters**
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
or
$stmt = $db->prepare("SELECT id FROM Employee WHERE name=:name");
$stmt->execute(array(':name' => $name));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Want to know more look at this link
if you are using inline coding in single page and not using oops than go with this full example, it will sure help
//connect to the db
$dbh = new PDO('mysql:host=localhost;dbname=mydb', dbuser, dbpw);
//build the query
$query="SELECT field1, field2
FROM ubertable
WHERE field1 > 6969";
//execute the query
$data = $dbh->query($query);
//convert result resource to array
$result = $data->fetchAll(PDO::FETCH_ASSOC);
//view the entire array (for testing)
print_r($result);
//display array elements
foreach($result as $output) {
echo output[field1] . " " . output[field1] . "<br />";
}

Categories