PDO emulate off, binding same value multiple times - php

I have the following bit of code in PHP7. I'm using PDO to connect to MySQL.
With PDO prepared statements emulation on, this code works successful:
$query = $db_con->prepare('SELECT * FROM matches WHERE matches.home_team_id=:team_id OR matches.away_team_id=:team_id');
$query->bindValue(':team_id', $team_id, PDO::PARAM_STR);
$query->execute();
return $query->fetchAll();
But with true PDO prepared statements (emulation off), the previous code gives an error that not enough values were bound. I'm forced to do the following:
$query = $db_con->prepare('SELECT * FROM matches WHERE matches.home_team_id=:team_id OR matches.away_team_id=:team_id2');
$query->bindValue(':team_id', $team_id, PDO::PARAM_STR);
$query->bindValue(':team_id2', $team_id, PDO::PARAM_STR);
$query->execute();
return $query->fetchAll();
This works, but is there any way I don't have to declare the same variable twice with true prepared statements? I have a lot of these queries, and would like to replace them all to use true prepared statements.
As someone asked in the comments: why do I want emulation off? I didn't really have a preference, but now it seems that true prepared statements are more strict than emulated statements. Is my understanding correct that is is better to develop with true prepared statements to guarantee it will work with both settings?

There is a way by change the query
$query=$db_con->prepare('SELECT*FROM matches WHERE :team_id in(home_team_id,away_team_id)');
$query->bindValue(':team_id', $team_id, PDO::PARAM_STR);
$query->execute();
This may not desirable, but it declare variable at once for case.
Hope this helpful.

A simple solution is to use a counter. In that way you can keep emulation off and still bind the same value multiple times without the need to count how many times you've used it, or renumber when you change the query.
$count=0;
$query = $db_con->prepare(
'SELECT * FROM matches WHERE
matches.home_team_id=:team_id'.(++$count).' OR
matches.away_team_id=:team_id'.(++$count)
);
for($i=1; $i<($count+1) ;++$i){
$query->bindValue(':team_id'.$i, $team_id, PDO::PARAM_STR);
}
$query->execute();
return $query->fetchAll();

Related

PHP Prepared Statement to delete all records

How do you delete all contents of a table in PHP MySQL using prepared statement? Do I have to use prepared statement to be safe or does using $deleteall = mysqli_query($conn,"DELETE FROM mytable;"); works with no difference?
Is this how it's supposed to be done:
$stmt = $conn->prepare("DELETE FROM mytable");
$stmt->execute();
There's no point in using prepared statements when you don't have parameters.
Prepared statements exist to make if efficient to execute a statement multiple times, possibly with different arguments. They also help with SQL injection prevention: you don't have to remember to apply quoting and escaping manually. But if you're going to run something only once there are no parameters, don't bother with prepared statements.
You may want to delete records with criteria parameters so the best way to do it:
$sqlQuery = "DELETE FROM TABLE_NAME WHERE id=?";
$statement = $conn->prepare($sqlQuery);
$statement->bind_param("i", $memberId);
$statement->execute();
Use this way, it is working fine on me. Hope it will help you.
$stmt= 'DELETE from mytable';
$result = $conn->prepare($stmt);
$result->execute();

How to use Functions to create Prepared Statements

I am new to these prepared statements (all my code so far has been procedural), and I was trying to create a function for executing prepared statements so I could save time writing a statement for every SQL query I need.
function executeQuery($stmt,$mysqli,$sql,$type,$param1,$param2,$param3){
$stmt = $mysqli -> stmt_init();
$stmt = $mysqli -> prepare($sql);
$stmt->bind_param($type,$param1,$param2,$param3);
$stmt->execute();
$stmt->close();
}
As you can see, my issue is that I would need a different function for prepared statements that only deal with 1 parameter in the query, one for 2 parameters, another for 3 and so on. I thought of making $param an array but I don't think that quite works.
Any ideas?

MySQLi prepared statement fails where identical regular query succeeds

I have a conventional query that works just fine that looks like this:
$result = $mysqli->query("SELECT value FROM activities WHERE name = 'Drywall'");
This succeeds in returning a row. However, for the purposes of diagnosing the problem I'm having with a prepared statement, I tried an identical query as a prepared statement like so:
$stmt = $mysqli->prepare("SELECT value FROM activities WHERE name = 'Drywall'");
$stmt->execute();
Despite the fact these are identical query strings, $stmt->num_rows is always 0. Why would the conventional query work, but the prepared statement not when they are the same exact query? Also, I realize including 'Drywall' in the prepared query string runs counter to the purpose of prepared statements, but I was just trying to eliminate the possibility that bind_param() was the culprit. So I was using bind_param() to fill in placeholders and that wasn't working either, despite my double-checking at runtime that the variable I was binding contained the correct value.
I think you want to use
$stmt->store_result();
before the call
$stmt->num_rows();
see last line of the descripton in the manual for $stmt->num_rows() (http://www.php.net/manual/en/mysqli-stmt.num-rows.php).
Check for proper use of the mysqli->prepare. The function depends on a parameter to be passed. It is different from passing the values ​​directly in the query but can use with another way.
Verify the manual:
http://www.php.net/manual/pt_BR/mysqli.prepare.php
Did you try something like this:
$stmt = $mysqli->prepare("SELECT value FROM activities WHERE name = 'Drywall'");
$stmt->execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();
PS:
Prepared statements are Good. I would urge you to ALWAYS consider using them.
But in this case, a simple query would be much more efficient (would incur fewer round trips) than a prepared statement.

Prepared MySQLi statements

I've always used PDO statements, but for some reason I can't persuade the server guy to install PDO for php, but I do have MySQLi, I have no clue what I'm doing wrong, I do not get a connection error and I do not get a query error no matter how I try to output one. Here's what I'm doing.
include 'MySQLiConnect.php';
if($stmt = $mysqli->prepare("SELECT * FROM zipCodeTable WHERE zip_code = ?")){
$stmt->bind_param("s", '07110');
$stmt->execute();
$stmt->bind_result($resultsArray);
$stmt->fetch();
foreach($resultsArray as $columnData){
$matchingZipcode = $columnData['zip_code'];
$matchingTimezone = $columnData['time_zone'];
}
$stmt->close();
}
echo $matchingZipcode.', '.$matchingTimezone;
This is basically just to confirm a users zipcode, never used MySQLi prepared statements before, I tryed to do it straight from the manual, not sure what I'm doing wrong. Thank you for taking the time to read this.
You're trying to "bind" a literal string. You can't do this. You must bind a variable.
Change
$stmt->bind_param("s", '07110');
To
$string = '07110';
$stmt->bind_param("s", $string);
Also, when you bind a result you must provide a variable for each field returned.
For example:
$stmt->bind_result($zipCode, $timeZone);
This is slightly problematic when using SELECT *. You might be interested in checking out this comment for how you might want to go about it: http://www.php.net/manual/en/mysqli-stmt.bind-result.php#85470

Using the LIKE operator with % for a keyword search with PDO prepared statements

I am trying to write a keyword search using PDO prepared statements. Ideally, I'd like to make use of the LIKE operator to search for a substring inside the field value. Here is my code:
$statement = $this->db->prepare("select * from whatever where title like ? or author like ?");
$statement->execute(array("%$titleKeyword%","%$authorKeyword%"));
$rows = $statement->fetchAll(PDO::FETCH_ASSOC);
Unfortunately, $rows is always empty when I try this. However, if I copy the SQL into phpMyAdmin, and substitute '%keyword%' for each of the ? symbols, it works fine (I get results when the keyword used exists).
I have also tried the following code:
$statement = $this->db->prepare("select * from whatever where title like :titleKeyword or author like :authorKeyword");
$statement->bindValue(":titleKeyword", '%'.$titleKeyword.'%', PDO::PARAM_STR);
$statement->bindValue(":authorKeyword", '%'.$authorKeyword.'%', PDO::PARAM_STR);
$statement->execute();
$rows = $statement->fetchAll(PDO::FETCH_ASSOC);
I had read in another question that you are supposed to include the % when binding the parameters, not in the SQL itself (pre-prepared statement), but that doesn't work.
I could resort to just inserting the keyword directly into the SQL (after doing some sanitization), but I want to stick with prepared statements. Any help would be greatly appreciated.
This actually works for me:
$stmt = $pdo->prepare("select * from t where c like ?");
$stmt->execute(array("70%"));
print_r($stmt->fetchAll());
What PHP version do you use?
Thanks Steffen and Terry for the help.
I ended up solving the problem myself by switching to bindParam() instead of bindValue(). I am not sure why I couldn't do it with bindValue(), but right now I am just too tired to care.

Categories