PDO prepared SELECT statement isn't working - php

i'm having a hard time trying to retrieve data from a table using PDO prepared statements,
Below is my code which isn't working, $post is always empty.
//connection to db has been made
$stmt = $db->prepare("SELECT * FROM posts WHERE id = ?");
$stmt->bindValue(1,$_GET['id']);
$post = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->execute();
I'm quite confident the problem occurs in the third line, so please let me know if there is another way to get the data rather than fetchAll(PDO::FETCH_ASSOC).
Thanks alot.

You're not actually executing the method, but otherwise, your code looks fine!
// Assuming $_GET['id'] has a value (thanks Mike!)
$stmt = $db->prepare("SELECT * FROM posts WHERE id = ?");
$stmt->bindValue(1, $_GET['id']);
$stmt->execute();
$post = $stmt->fetchAll(PDO::FETCH_ASSOC);
As an aside, I'd also make sure that $_GET['id'] is valid; is_int($_GET['id']) returns a boolean that could help.
After fetching your posts, make sure to iterate through them.
if($post != null && count($post) > 0) {
for($i = 0; $i < count($post); $i++) {
echo $post[$i]['title'] . '<br />';
}
}

Related

Will overriding the variable holding a prepared statement close the statement?

Some people recommends calling close() on a prepared statement when I am done with the result of a query.
I often reuse the same variable name for the prepared statement, so I was wondering if overriding the variable automatically calls close() on the prepared statement ?
Example of how I currently do it (The SQL is made up for the examples):
// Fetch the requested user
$stmt = $mysqli->prepare("SELECT * FROM user WHERE id = ?");
$stmt->bind_param("i", $_GET['userid']);
$stmt->execute();
$user = $stmt->get_result()->fetch_assoc();
// Fetch all posts associated with the user
$stmt = $mysqli->prepare("SELECT * FROM posts WHERE user_id = ?");
$stmt->bind_param("i", $user['id']);
$stmt->execute();
$result = $stmt->get_result();
$posts = array();
while ($row = $result->fetch_assoc()) {
$posts[] = $row;
}
Should I call $stmt->close(); between fetching the user and fetching the posts or is it done when I override $stmt by calling $stmt = $mysqli->prepare(...); ?
Yes, most of the time, because PHP will try to clean up objects which have no reference as soon as possible. That means that once you overwrite it, there will be no more references to the old object and PHP will clean it up. Part of cleaning up mysqli_stmt object involves closing the statement.
But the reason why some people recommend calling $stmt->close() explicitely is to avoid errors such as this:
mysqli_sql_exception: Commands out of sync; you can't run this command now in ...
This error happens when you have not fetched all results from MySQL and you try to create a new statement by calling prepare or query. MySQL will not let you execute anything else until you fetch all remaining rows. This is usually achieved with get_result() or store_result(). If you always fetch the results in their entirety then you really don't need to worry much about when exactly the statement gets closed. Let PHP take care of it for you.
The best course of action is to avoid using mysqli functions directly. You should write some simple function which will encapsulate all the mysqli functionality so that you never have to worry about this low-level stuff. A sample function could look like this:
function safeQuery(\mysqli $db, string $sql, array $params = []): ?array {
$stmt = $db->prepare($sql);
if ($params) {
$stmt->bind_param(str_repeat("s", count($params)), ...$params);
}
$stmt->execute();
if ($result = $stmt->get_result()) {
return $result->fetch_all(MYSQLI_BOTH);
}
return null;
}
$result = safeQuery($mysqli, 'SELECT * FROM user WHERE id = ?', [$_GET['userid']]);
if ($result) {
$user = $result[0];
$posts = safeQuery($mysqli, 'SELECT * FROM posts WHERE user_id = ?', [$user['id']]);
foreach ($posts as $post) {
}
}

Writing a Select Where statement in PHP and MySQL

Would someone please me with the code below, I am inexperienced in this area and my class in SQL was "A long time ago in a galaxy far, far away..." I know the connection string works because I have used it in other functions with this app. I have even used the code below for retrieving *rows from another table in another function, for the most part, except that I didn't use the WHERE clause.
First, I am able to store IP addresses in the table using a function and it is working well. Now I want to check to see if a given one exist in this table. Partial code is given below.
What seems to always return is 0 rows. I have put in test data into the table and hard-coded the $ipA, but I still get 0 rows return. Please help if possible and thanks for the effort spent.
function checkDB($ipA) {
require_once('connection.inc.php');
$resultAns = "";
//create db connection
$conn = dbConnect();
//init prepared stmt
$stmt = $conn->stmt_init();
//Set sql query for ipAddress search
//prepare the SQL query
$sql = 'SELECT * FROM ipAddress WHERE ipA = ?';
//submit the query and capture the result
if ($stmt->prepare($sql)) {
$stmt->bind_param('s', $ipA);
$stmt = $stmt->execute();
//if qry triggers error affeted_rows value becomes -1 &
//php treats -1 as true; so test for greater than 0
$numRows = $stmt->num_rows; //not to sure about the syntax here
}
// I want to know if the query brought back something or not, I don't what
// to know exactly what, only that it found a match or did not find a match.
// echos are for testing purposes to show me where I am landing.
if ($numRows == 0) {
echo '<script type="text/javascript">window.alert("numRows = 0")</script>';
$resultAns = 0;
} elseif ($numRows == 1) {
echo '<script type="text/javascript">window.alert("numRows = 1")</script>';
$resultAns = 1;
}
return $resultAns;
}
Try storing the result after you execute
$stmt->store_result();
Use $stmt->store_result(); before you call num_rows.
While the others caught one reason that $numRows would never receive a value other than 0, the other piece of code that was flawed and caused problems was...
$stmt = $stmt->execute(); which should have been just $stmt->execute();
I must have mixed it up with other code I wrote from somewhere else.
Thanks for the answers, they did help.

SQL query in Foreach loop using array variable

UPDATE:
WORKING CODE, Thanks jon for the push in the right direction.
<?php
$stmt2 = $conn->prepare("SELECT * FROM userItems WHERE id=:id");
foreach ($moodItems as $id2)
{
// bind the parameters
$stmt2->bindValue(":id", $id2);
if ($stmt2->execute()) {
if($result = $stmt2->fetch(PDO::FETCH_ASSOC)) {
// initialise an array for the results
$itemName2 = $result['itemName'];
$name2 = $result['userId'];
echo $itemName2."<br>";
echo $name2."<br>";
}
}
}
?>
I am having trouble using a SQL query in a foreach loop. I am trying to use the value from the first query(which is an array) and use it in the second query.
The first query works correctly to give me the proper value(array).But for some reason when I try to use the array in the foreach it does not work properly, it does not show any errors...it just does not fetch any data from the database.
IE/ echo $itemName2; <----does not get any info from database
Any help would be great. Thanks.
here is the code I am working with:
<?php
$attrs = array(PDO::ATTR_PERSISTENT => true);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// prepare the statement.
$stmt = $conn->prepare("SELECT * FROM userMoodboard WHERE name=:name");
// bind the parameters
$stmt->bindValue(":name", $loggedInUser->username);
// initialise an array for the results
if ($stmt->execute()) {
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$imageUrl = $row['imageUrl'];
$moodItems = $row['moodItems'];
$moodItems = json_decode($moodItems);
?>
<img src='<?php echo $imageUrl;?>' class="thumbnail"></img>
<?php
$stmt = $conn->prepare("SELECT * FROM userItems WHERE id=:id");
foreach ($moodItems as $id)
{
// bind the parameters
$stmt->bindValue(":id", $id);
// initialise an array for the results
if($stmt->execute()) {
$itemName2 = $row['itemName'];
$name2 = $row['userId'];
echo $itemName2;
echo $name2;
}
}
}
}
?>
There are a couple of things wrong with your code, but we'll start with your second statement.
$stmt = $conn->prepare("SELECT userId FROM userItems WHERE id=:id");
foreach ($moodItems as $id)
{
// bind the parameters
$stmt->bindValue(":id", $id);
// initialise an array for the results
if($stmt->execute()) {
$itemName2 = $row['itemName'];
$name2 = $row['userId'];
echo $itemName2;
echo $name2;
}
}
You are trying to pull out $row['itemName'] and $row['userId'], however, you never SELECT the itemName column in that query. So if you want that information, you'll have to select it first. Aside from that, you execute the query, but you never fetch the row with information.
Those are the basics of why the second portion will not work how you want it to.
Now, for the bigger picture. Most of the block of code you provide is a nested if for your first $stmt->execute() and then within a while($row = ... Which, by itself is fine. However, later within the same block, you prepare another statement, which is perfectly acceptable, but you assign it to the same $stmt variable that you are using for the loop in the first place, which will also cause you problems. You'll want to assign a new variable for your second prepared statement, so you can work with the new data-set. Also, going back to the previous block I posted in, you'll want to fetch it to a variable that is not $row, as that is also a used variable.
UPDATE: As pointed out by Jon, my answer applies to Zend_Db_Adapter and not to PDOStatement (which you are using). My apologies.
The problem probably is that you're doing $stmt->execute() on the second SQL query. execute() does not return results, what you want to do is to fetch(), which does return results.

Initializing variable from PDO query

$q = $db->query(" SELECT username FROM users WHERE userident = '1' ");
echo $q; //error
print_r $q; //prints the query information (SELECT ... etc)
How do I go about getting the specific value of the element I am querying? Say the element under column username and where userident equals '1' contains the value "Patrick"; how do I initialize this string into a variable?
//same query as above
$user = $q;
echo $user; //prints "Patrick"
Sorry if this is something so rudimentary and mundane, but I've never done this outside of a foreach() loop. I'd normally iterate through rows to print specific details. The below works, but the foreach() is unnecessary as far as I understand.
foreach($q as $p) {
$user = $p["username"];
}
echo $print; //this correctly prints "Patrick"
Surely there's a method I missed somewhere?
Using the query method pretty much defeats the purpose of using prepared statements. Plus, I believe for what you're looking for, it isn't quite right.
<?php
if (!isset($_POST['id'])) {
exit;
}
$userId = $_POST['id'];
$db = new PDO(/* Stuff */);
$sql = '
SELECT username
FROM users
WHERE id = :id';
// Get a prepared statement object.
$statement = $db->prepare($sql);
// Bind a parameter to the SQL code.
$statement->bindParam(':id', $userId, PDO::PARAM_INT);
// Actually get the result.
$result = $statement->fetch(PDO::FETCH_ASSOC);
// Close the connection.
$statement->closeCursor();
// Print the result.
print_r($result);
Alternately you can use $statement->fetchAll() to gather more than one result.
Edit: I didn't actually run this code, so you might have to tinker with it to get it working right.

How to use mysqli bind_result

im trying to use mysqli with bind_result but all i get is null values. My $stmt
number of rows is greater than 0 so i do have some data in it.
I dont realy understand what value should come into bind_result
I have read at the manual http://php.net/manual/en/mysqli-stmt.bind-result.php
And they dont explain what should i put in the bind_result.
Should i put there the column names? if yes, as strings? how do i get my wanted values?
Here is my code thanks for helping:
$sql = "SELECT * FROM comments WHERE workout_name = ? AND user = ?";
$stmt = $mysqli->prepare($sql) or trigger_error($mysqli->error."[$sql]");
$stmt->bind_param('ss', $workout_name, $user);
$workout_name = "rytg";
$user = "tomer";
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($comment, $commented_user);
if($stmt->num_rows > 0)
{
$response["workouts"] = array();
while ($stmt->fetch())
{
// temp user array
$workouts = array();
$workouts["comment"] = $comment;
$workouts["user"] = $commented_user;
// push single product into final response array
array_push($response["workouts"], $workouts);
}
}
Your only problem is insufficient error reporting
error_reporting(E_ALL);
ini_set('display_errors',1);
Just add these lines at the top of your code and you will be immediately informed of the exact problem with your code.
Note that on the production server you have to turn displaying errors off and logging on
I don't have a working PHP installation next to me at the moment, so I can't verify it, but I believe you might have to bind both parameters and result before you execute the query, like so:
$workout_name = "rytg";
$user = "tomer";
$stmt = $mysqli->prepare($sql) or trigger_error($mysqli->error."[$sql]");
$stmt->bind_param('ss', $workout_name, $user);
$stmt->bind_result($comment, $commented_user);
$stmt->execute();
I'm not too sure about store_result() either. I don't recall having to use it while retrieving the results, so you might want to try running your code without it and see what happens.

Categories