loop prepare statements, what needs to be repeated? - php

I'm using statements to protect against sql injections... My question is what do i need to repeat when looping multiple queries?
If you look at the second query, im not sure if the prepare statement needs to be insde the foreach loop
Something wrong with this summary code?
open database connection
// connect to database
$conn = connect('r');
launch first query
$sql = "SELECT ... FROM ... WHERE xxx = ?";
$stmt = $conn->stmt_init();
$stmt->prepare($sql);
$stmt->bind_param('i', $albumid);
$stmt->bind_result(..., ...);
$stmt->execute();
$stmt->store_result();
$num_rows = $stmt->num_rows;
if ($num_rows > 0) {
loop results...
}
$stmt->free_result();
second query with repeats:
$sql = "SELECT ... FROM ... WHERE xxx = ?";
$stmt = $conn->stmt_init();
$stmt->prepare($sql); ///??????? inside or outside foreach loop ?????
foreach (... as $key => ...) {
$stmt->bind_param('i', $key);
$stmt->bind_result(...);
$stmt->execute();
$stmt->store_result();
$num_rows = $stmt->num_rows;
if ($num_rows > 0) {
loop results...
}
$stmt->free_result();
}
close database
// close database
$conn->close();

You don't have to prepare the query multiple times. Just bind the parameters and execute it multiple times.
From the PHP Manual:
For a query that you need to issue multiple times, you will realize
better performance if you prepare a PDOStatement object using
PDO::prepare() and issue the statement with multiple calls to
PDOStatement::execute().
Hope this helps.

Related

Binding the same variable more than once for mysqli

I have a site in which I need to rewrite all the SQL to be prepared statements in the MySQLi Prepared format.
Similar to the below
$sql = "SELECT * FROM jobs WHERE Job_Id = ?";
// Prepare statement
$stmt = $dbcon->prepare($sql);
// Bind parameters
$stmt->bind_param('i', $Job_Id);
// Execute statement
$stmt->execute();
// Bind result
$result = $stmt->get_result();
if($result->num_rows >= 1){
while($row = $result->fetch_assoc()){
}
}
I came across this line:
UPDATE jobs SET jobTitle = IF('$jobTitle' = '', jobTitle, '$jobTitle'),
How would this query line be represented in a prepared statement? Surely all the variables would be replaced with ?, but then do I have to re-use the same variable and have more placeholders?

query execution with prepared statements not working

i am using ajax to display dynamic data on my website! previously it was done using simple mysqli queries now i am improving my website's security by adding prepared statements,i have two queries one is written in mysqli and other in prepared statements here's the mysqli query
$sql = "SELECT DISTINCT model_trim FROM `tbl_02_models` WHERE model_year='$year' and model_name='$model' and model_make_id='$make' ";
$run = mysqli_query($db, $sql);
while ($row = mysqli_fetch_array($run)) {
if($row['model_trim']){
$data2[$i]['model_trim']=$row['model_trim'];
$i++;
}
}
and here's the prepared statement query
$query="SELECT DISTINCT model_trim FROM `tbl_02_models` WHERE model_year=? and model_name=? and model_make_id=?";
$stmt = $db->prepare($query);
if($stmt){
$stmt->execute();
$stmt->bind_param("iss",$year,$model,$make);
$stmt->bind_result($model_trim);
while ($stmt->fetch())
{
if($model_trim)
{
$data2[$i]['model_trim']=$model_trim;
$i++;
}
}
$stmt->close();
}
the query written in simple mysqli is working fine but when i am using the same query in prepared statements it is returning me null! any idea?
Execute method is called after bind the comments.
Try below code :
$query="SELECT DISTINCT model_trim FROM `tbl_02_models` WHERE model_year=? and model_name=? and model_make_id=?";
$stmt = $db->prepare($query);
if($stmt){
$stmt->bind_param("iss",$year,$model,$make);
$stmt->bind_result($model_trim);
$stmt->execute();
while ($stmt->fetch())
{
if($model_trim)
{
$data2[$i]['model_trim']=$model_trim;
$i++;
}
}
$stmt->close();
}
For more reference follow this link - http://www.w3schools.com/php/php_mysql_prepared_statements.asp

PHP, MySQL statement results in ZERO rows

hope someone can help me.
i have a very simple prepared SELECT statment in PHP:
$query_select = ("SELECT * FROM companies where user_name = ? ");
$stmt = $mysqli->prepare($query_select);
$stmt->bind_param("s", $user_name);
$stmt->execute();
$count = $stmt->num_rows;
in companies table I have several rows with the $user_name i`m trying to query. But i still get 0 rows as a result.
The strange thing is that the non PREPARED version works:
$query = 'SELECT * FROM companies WHERE user_name="'.$user_name.'"';
$result = $mysqli->query($query);
$count= $result->num_rows;
echo "Aantal: ".$count;
So my question is, does anyone know why the prepared version returns ZERO and the non prepared version returns the correct number of rows?
Add this line to your code between execute and num_rows statement.
$stmt->store_result();
You have to store it before counting it.
For mysqli prepared statements, you must take an additional step: storing the result.
Try this:
$query_select = ("SELECT * FROM companies where user_name = ? ");
$stmt = $mysqli->prepare($query_select);
$stmt->bind_param("s", $user_name);
$stmt->execute();
$stmt->store_result(); // <-- new line
$count = $stmt->num_rows;
May be you need to bind the result:
/* bind result variables */
$stmt->bind_result($district);
Full example here

Order of execution for prepared statement in php

I've read everything there is to read about prepared statements and im still not sure about the order of execution... (many use different order).
Is this a good order ?
$sql = 'SELECT * FROM ... WHERE ... = ?';
$conn = ...connection to database...
$stmt = $conn->stmt_init();
$stmt->prepare($sql);
$stmt->bind_param('i', $param);
$stmt->execute();
$stmt->store_result(); // results are cached and accessed from memeory, therefore faster but use more memory
$num_rows = $stmt->num_rows; // how many? (can only be use with store_result() )
$stmt->bind_result($column, ...);
$stmt->fetch(); // use in loop if necessary
$stmt->free_result(); // use only with store_result()
$stmt->close(); // close prepared statement
$conn->close(); // close database
Apparently not.
Although order is quite all right, many operators you have used are superfluous and useless. Also, there should be no connection related code in the context of execution single query.
include 'db.php'; // here goes connect
$sql = 'SELECT * FROM ... WHERE ... = ?';
$stmt->prepare($sql);
$stmt->bind_param('i', $param);
$stmt->execute();
$stmt->bind_result($column, ...);
$stmt->fetch();
is enough. Note that you never need row_count if you have data.

Close statement object before starting a new with prepared statements

I'm quite new at using prepared statements and is wondering if I should close the stmt_init() after each call or could I just keep it open?
$stmt = $mysqli->stmt_init();
if($stmt->prepare("SELECT player_draws, player_turn, player_passes, swapped FROM ".$prefix."_gameplayer WHERE fk_game_id = ? AND fk_player_id = ?")){
$stmt->bind_param('ii', $currgame, $playerid);
$stmt->execute();
$stmt->bind_result($udraws, $uturn, $upass, $uswaps);
$stmt->fetch();
echo $udraws.'-'.$uturn.'-'.$upass.'-'.$uswaps.'<br>';
// Close statement object
$stmt->close();
}
$stmt = $mysqli->stmt_init();
if($stmt->prepare("SELECT player_draws, player_turn, player_passes, swapped FROM ".$prefix."_gameplayer WHERE fk_game_id = ? AND fk_player_id != ?")){
$stmt->bind_param('ii', $currgame, $playerid);
$stmt->execute();
$stmt->bind_result($odraws, $oturn, $opass, $oswaps);
$stmt->fetch();
echo $odraws.'-'.$oturn.'-'.$opass.'-'.$oswaps.'<br>';
// Close statement object
$stmt->close();
}
Is one of them better for the database considering calls?
Thanks in advance!
...A prepared statement or a parameterized statement is used to execute the same statement repeatedly with high efficiency...
EDIT
Since the queries are different each of them will need to be prepared separately but you should be able to reuse the $mysqli->stmt_init();
On a side note someone mentions this in the comments:
*if you are repeating an statement in an loop using bind_param and so on inside it for a larger operation. i thougt id would be good to clean it with stmt->close. but it broke always with an error after aprox. 250 operations . As i tried it with stmt->reset it worked for me.*

Categories