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
Related
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.
The php manual seems to be a little light regarding the mysqli extension and I am not finding any information poking with Google.
When I create a mysqli prepared statement, should the order of calls be
mysqli::prepare()
mysqli::stmt::bind_param()
mysqli::stmt::execute()
mysqli::stmt::store_result()
mysqli::stmt::bind_result()
or
mysqli::prepare()
mysqli::stmt::bind_param()
mysqli::stmt::execute()
mysqli::stmt::bind_result()
mysqli::stmt::store_result()
Furthermore, if I then want to change the parameters and reexecute the statement, should I use
mysqli::free_result()
mysqli::stmt::execute()
mysqli::stmt::store_result()
mysqli::bind_result()
or can I simply use execute() again and then use free_result() once I am finished using the statement?
It is not PHP manual but mysqli extension itself being unclear and ambiguous.
However, to clear your confusion
You can call store_result() anywhere you wish between prepare() and fetch(). As a matter of fact, bind_result() is just a supplementary function for fetch().
In PHP you rarely need to free anything in general, and especially in cases like this, when result going to be overwritten in the next call. So - yes, you can simply call execute() again (with bind_param() first).
Also note that some installations will let you call get_result which makes all that process with fetching variables at least sensible. But is isn't always available
Also note that neither bind_param() nor bind_result() will let you easily bind an arbitrary number of variables, which will make code even more bloated.
So, looking at all that mess I'd still suggest you to use either PDO or manually implemented placeholders, like safeMysql does.
here is an example that works:
$query="SELECT service_ip,service_port FROM users WHERE username=? and password=?";
$conn=connection();
$stmt = $conn->prepare($query);
$stmt->bind_param('ss', $user,$pass);
$ans=$stmt->execute();
$service_ip=false;
$service_port=false;
$stmt->bind_result($service_ip,$service_port);
$stmt->fetch();
mysqli_free_result($ans);
$stmt->close();
$conn -> close();
Here is proper code:
$query="SELECT service_ip,service_port FROM users WHERE username=? and password=?";
$stmt = $conn->prepare($query);
$stmt->execute(array($user,$pass));
$data = $stmt->fetch()/fetchAll()/fetchColumn();
// whoops! that's all
// ...in case you want to execute again
$stmt->execute(array($user2,$pass2));
$data = $stmt->fetch()/fetchAll()/fetchColumn();
// and again...
$stmt->execute(array($user3,$pass3));
$data = $stmt->fetch()/fetchAll()/fetchColumn();
Note that you already have all required data. Feel the power of PDO
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.
I had a quick question with regard to prepared statements within PHP. I was previously using the mysql_query function to manipulate database data, but was told that for security issues I should consider using prepared statements. I have made the transition, but I have a few questions on how to detect whether a query has failed.
Below I have a piece of example code. The $con variable is a connection which is specific depending on the query I am attempting, in this case the connection would be to my database through an account with only select permissions.
$stmt = $con->stmt_init();
$stmt->prepare("SELECT COUNT(*) FROM users WHERE username=?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->bind_result($user_count);
$stmt->fetch();
$stmt->close();
I was wondering how one can detect failure within any of these steps? The most simple solution I can imagine would be simply to wrap the code using a try/catch.. but I was wondering if there is a more sophisticated way of doing this.
Thanks for reading my question.
To expand on Jared's comment, you could do the following:
$stmt->execute();
if( !$stmt->errorCode() ){
// do something with results
}else{
// do something with the error
}
$stmt->close();
I am trying to make a query with a prepared statement to retrieve some information and make another query with the information that was received from the first query, but i am receiving the error:
Cannot pass parameter by reference
is there a way around this?
this is my code:
$DBH = getDBH();
$stmt = $DBH->prepare("SELECT small FROM info WHERE user = ?");
$stmt->bind_param("s",$userid);
$stmt->execute();
$stmt->bind_result($small);
$stmt->fetch();
$stmt->close();
$stmt = $DBH->prepare("INSERT INTO method(small) VALUES(?)");
$stmt->bind_param("s",$small);
$stmt->execute();
$stmt->close();
I think i may have got it to work by adding
return $small;
after
$stmt->fetch();
although i have not had time to test it with any actual values, I am not recieving any errors, but i am unsure if the code stops at
return $small;
or if everything continues to execute, i may be able to just rewrite it into a function and return the value.
Edit: Never mind the below! I was thinking of PDO
Try changing the following lines:
$stmt = $DBH->prepare("SELECT small FROM info WHERE user = :s");
and
$stmt = $DBH->prepare("INSERT INTO method(small) VALUES(:s)");
It's because you're trying to bind a nonexistent parameter. If you want to use question marks, you have to find it like so If I remember correctly.
$stmt->bind_param(0,$userid);