PHP MySQL query not returning all results - php

My following SQL query in PHP does not work fully. The result only contains the first row. The query works totally fine inside PHPMyadmin, which returns me all the results.
$select = "SELECT a.setID, a.setName, a.setPrimaryLanguage, a.setSecondaryLanguage
FROM Person_Set ps, Album a
WHERE ps.Person_username = :username
AND ps.Set_setID = a.setID";
try {
$stmt = $dbh->prepare($select, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->bindValue(":username", $username, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetch();
echo json_encode($result);
unset($stmt);
} catch (Exception $e) {
echo 'Exception : ' . $e->getMessage() . "\n";
}
Besides, if I change the selection criteria to search for rows containing certain string, the result is empty (returned 'false'). Query below:
$select = "SELECT a.setID, a.setName, a.setPrimaryLanguage, a.setSecondaryLanguage
FROM Album a, Set_Card s
WHERE a.setName LIKE '%:searchText%'
AND a.setID = s.Set_setID
GROUP BY a.setID";
I have been trying different ways to connect to MySQL and get the results, like
$results = $mysqli->query($query);
instead of using PDO. However, the results are still the same. Could anyone help to point out where my mistakes are? Thank you very much!

PDOStatement::fetch — Fetches the next row from a result set
So when you just do a fetch it fetches the first row, unless you do it using a loop which changes the cursor to the next record.
You may get all the records using fetchAll method
http://php.net/manual/en/pdostatement.fetch.php
http://php.net/manual/en/pdostatement.fetchall.php

PDOStatement::fetch fetches a single row and moves pointer to the next row. You will either use $results = $stmt->fetchAll() to retrieve all results or a loop like this:
while ($result = $stmt->fetch()) {
echo json_encode($result);
}

Hi you are using fetch() function which fetch only one row instead use this code,
$select = "SELECT a.setID, a.setName, a.setPrimaryLanguage, a.setSecondaryLanguage
FROM Person_Set ps, Album a
WHERE ps.Person_username = :username
AND ps.Set_setID = a.setID";
try {
$stmt = $dbh->prepare($select, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->bindValue(":username", $username, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchall();
echo json_encode($result);
unset($stmt);
} catch (Exception $e) {
echo 'Exception : ' . $e->getMessage() . "\n";
}

Related

$result Always return 1 , instead of wanted ID from database

My problem is, how to make my code, return ID that is assigned to person i have in database, instead of 1-which i dont know from it comes.
Opiekun Prawny:<select id="text_box_od" name="fullname_opiekun" >
<?php
while($rows = $resultimie->fetch_assoc())
{
$full_name_opiekun = $rows['full_name_opiekun'];
echo "<option value='$full_name_opiekun'>$full_name_opiekun</option>";
}
?>
</select>
<?php
$con=mysqli_connect('localhost','root','','aplikacja_kolonijna');
if(!$con)
{
echo 'Data base not found';
}
$fullname_opiekun = $_POST['fullname_opiekun'];
$check = "SELECT id_opiekun FROM opiekun where concat(imie_opiekun,' ',nazwisko_opiekun,' - ',pesel_opiekun) like '$fullname_opiekun'";
$query = mysqli_query($con,$check);
$result = intval(mysqli_fetch_row($query));
echo $result;
echo $fullname_opiekun;
Actually person i'm calling is " Kazimierz Kowalczyk 14212312312"
and it's person i have in my database , but with ID 3.
My code, instead of return 3, when i check echo $result; , return 1, all the time, and i have now idea, how to make it work like i want.
When i'm checking echo $full_name_opiekun; it shows me that my SELECT works and returns to me " Kazimierz Kowalczyk 14212312312"... why i can't get right ID?
You need to remember that when you have some input to pass into SQL you must use prepared statements and bind the parameters. If you use prepared statements then to fetch a single value from the result you only need to use $stmt->bind_result($yourVariable) and then $stmt->fetch()
I have fixed your code and also switched error reporting on. You should always make sure it is on.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$con = mysqli_connect('localhost', 'root', '', 'aplikacja_kolonijna');
$con->set_charset('utf8mb4'); // always set the charset
$fullname_opiekun = $_POST['fullname_opiekun'];
// Execute the query
$check = "SELECT id_opiekun FROM opiekun where concat(imie_opiekun,' ',nazwisko_opiekun,' - ',pesel_opiekun) like ?";
$stmt = $con->prepare($check);
$stmt->bind_param('s', $fullname_opiekun);
$stmt->execute();
// Bind the first column as a result
$stmt->bind_result($result);
$stmt->fetch(); // Fetch the value
echo $result;
echo $fullname_opiekun;
Don't cast the result array to an integer. You need to use the index.
You also should use prepared statements with parameterized queries, and use the error reporting function so you know when errors are returned.
$fullname_opiekun = $_POST['fullname_opiekun'];
$check = "SELECT id_opiekun FROM opiekun where concat(imie_opiekun,' ',nazwisko_opiekun,' - ',pesel_opiekun) like ?";
if ($stmt = mysqli_prepare($con, $check)) {
mysqli_stmt_bind_param($stmt, "s", $fullname_opiekun);
mysqli_stmt_bind_result($stmt, $id_opiekun);
mysqli_stmt_fetch($stmt);
echo $id_opiekun;
mysqli_stmt_close($stmt);
} else {
printf("Error message: %s\n", mysqli_error($con));
}
Don't complicate, this is enough:
//...
$check = "SELECT id_opiekun FROM opiekun where concat(imie_opiekun,' ',nazwisko_opiekun,' - ',pesel_opiekun) like '$fullname_opiekun'";
$query = mysqli_query($con,$check);
$result = mysqli_fetch_row($query);
echo $result[0]; // as `fetch_row` returns 0-indexed array
// example to fetch associative array:
//$result = mysqli_fetch_assoc($query);
//echo $result['id_opiekun'];

Having trouble fetching results from a MySQL table with PDO

I'm building a simple login system. What I'm having trouble with is fetching the password hash from the database.
This is what I have:
$statement = 'SELECT Pass FROM Emails WHERE Email = "?"';
$question = array($email);
try {
$DB->beginTransaction();
$preparedStatement = $DB->prepare($statement);
$preparedStatement->execute($question);
$resultArr = $preparedStatement->fetchAll();
print_r($resultArr);
$DB->commit();
} catch(\PDOException $ex) {
echo "Seriously bad error. ";
echo $ex->getMessage();
return false;
}
My problem is that $resultArr always contains no elements.
I know the SQL query itself works, as I've tested it directly in MySQL.
I believe that I have to use a prepared statement, as I'm sending user input to MySQL and have to defend against easy SQL injection attacks.
I'm using fetchAll() in order to make sure that there's only one result for a given email. Otherwise, there will be a huge problem.
What is my mistake here?
Just for sake of cleaning this extremely superfluous code
$stmt = $DB->prepare('SELECT Pass FROM Emails WHERE Email = ?');
$stmt->execute(array($email));
$pass = $stmt->fetchColumn();
these 3 lines is ALL you need to run a query and get result.
And yes, the problem is just quotes around ? mark.
To ensure there is no other email you ought to use unique index in Mysql
$query = 'SELECT Pass FROM Emails WHERE Email = :email';
try {
$DB->beginTransaction();
$preparedStatement = $DB->prepare($query);
$preparedStatement->bindParam("email", $email, PDO::PARAM_STR);
$preparedStatement->execute();
$resultArr = $preparedStatement->fetchAll();
print_r($resultArr);
$DB->commit();
} catch(\PDOException $ex) {
echo "Seriously bad error. ";
echo $ex->getMessage();
return false;
}

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.

PHP Commands Out of Sync error

I am using two prepared statements in PHP/MySQLi to retrieve data from a mysql database. However, when I run the statements, I get the "Commands out of sync, you can't run the command now" error.
Here is my code:
$stmt = $mysqli->prepare("SELECT id, username, password, firstname, lastname, salt FROM members WHERE email = ? LIMIT 1";
$stmt->bind_param('s', $loweredEmail);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($user_id, $username, $db_password, $firstname, $lastname, $salt);
$stmt->fetch();
$stmt->free_result();
$stmt->close();
while($mysqli->more_results()){
$mysqli->next_result();
}
$stmt1 = $mysqli->prepare("SELECT privileges FROM delegations WHERE id = ? LIMIT 1");
//This is where the error is generated
$stmt1->bind_param('s', $user_id);
$stmt1->execute();
$stmt1->store_result();
$stmt1->bind_result($privileges);
$stmt1->fetch();
What I've tried:
Moving the prepared statements to two separate objects.
Using the code:
while($mysqli->more_results()){
$mysqli->next_result();
}
//To make sure that no stray result data is left in buffer between the first
//and second statements
Using free_result() and mysqli_stmt->close()
PS: The 'Out of Sync' error comes from the second statement's '$stmt1->error'
In mysqli::query If you use MYSQLI_USE_RESULT all subsequent calls will return error Commands out of sync unless you call mysqli_free_result()
When calling multiple stored procedures, you can run into the following error: "Commands out of sync; you can't run this command now".
This can happen even when using the close() function on the result object between calls.
To fix the problem, remember to call the next_result() function on the mysqli object after each stored procedure call. See example below:
<?php
// New Connection
$db = new mysqli('localhost','user','pass','database');
// Check for errors
if(mysqli_connect_errno()){
echo mysqli_connect_error();
}
// 1st Query
$result = $db->query("call getUsers()");
if($result){
// Cycle through results
while ($row = $result->fetch_object()){
$user_arr[] = $row;
}
// Free result set
$result->close();
$db->next_result();
}
// 2nd Query
$result = $db->query("call getGroups()");
if($result){
// Cycle through results
while ($row = $result->fetch_object()){
$group_arr[] = $row;
}
// Free result set
$result->close();
$db->next_result();
}
else echo($db->error);
// Close connection
$db->close();
?>
I hope this will help
"Commands out of sync; you can't run this command now"
Details about this error can be found in the mysql docs. Reading those details makes it clear that the result sets of a prepared statement execution need to be fetched completely before executing another prepared statement on the same connection.
Fixing the issue can be accomplished by using the store result call. Here is an example of what I initially was trying to do:
<?php
$db_connection = new mysqli('127.0.0.1', 'user', '', 'test');
$post_stmt = $db_connection->prepare("select id, title from post where id = 1000");
$comment_stmt = $db_connection->prepare("select user_id from comment where post_id = ?");
if ($post_stmt->execute())
{
$post_stmt->bind_result($post_id, $post_title);
if ($post_stmt->fetch())
{
$comments = array();
$comment_stmt->bind_param('i', $post_id);
if ($comment_stmt->execute())
{
$comment_stmt->bind_result($user_id);
while ($comment_stmt->fetch())
{
array_push($comments, array('user_id' => $user_id));
}
}
else
{
printf("Comment statement error: %s\n", $comment_stmt->error);
}
}
}
else
{
printf("Post statement error: %s\n", $post_stmt->error);
}
$post_stmt->close();
$comment_stmt->close();
$db_connection->close();
printf("ID: %d -> %s\n", $post_id, $post_title);
print_r($comments);
?>
The above will result in the following error:
Comment statement error: Commands out of sync; you can't run this command now
PHP Notice: Undefined variable: post_title in error.php on line 41
ID: 9033 ->
Array
(
)
Here is what needs to be done to make it work correctly:
<?php
$db_connection = new mysqli('127.0.0.1', 'user', '', 'test');
$post_stmt = $db_connection->prepare("select id, title from post where id = 1000");
$comment_stmt = $db_connection->prepare("select user_id from comment where post_id = ?");
if ($post_stmt->execute())
{
$post_stmt->store_result();
$post_stmt->bind_result($post_id, $post_title);
if ($post_stmt->fetch())
{
$comments = array();
$comment_stmt->bind_param('i', $post_id);
if ($comment_stmt->execute())
{
$comment_stmt->bind_result($user_id);
while ($comment_stmt->fetch())
{
array_push($comments, array('user_id' => $user_id));
}
}
else
{
printf("Comment statement error: %s\n", $comment_stmt->error);
}
}
$post_stmt->free_result();
}
else
{
printf("Post statement error: %s\n", $post_stmt->error);
}
$post_stmt->close();
$comment_stmt->close();
$db_connection->close();
printf("ID: %d -> %s\n", $post_id, $post_title);
print_r($comments);
?>
A couple things to note about the above example:
The bind and fetch on the statement still works correctly.
Make sure the results are freed when the processing is done.
For those of you who do the right thing and use stored procedures with prepared statements.
For some reason mysqli cannot free the resources when using an output variable as a parameter in the stored proc. To fix this simply return a recordset within the body of the procedure instead of storing the value in an output variable/parameter.
For example, instead of having SET outputVar = LAST_INSERT_ID(); you can have SELECT LAST_INSERT_ID(); Then in PHP I get the returned value like this:
$query= "CALL mysp_Insert_SomeData(?,?)";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("is", $input_param_1, $input_param_2);
$stmt->execute() or trigger_error($mysqli->error); // trigger_error here is just for troubleshooting, remove when productionizing the code
$stmt->store_result();
$stmt->bind_result($output_value);
$stmt->fetch();
$stmt->free_result();
$stmt->close();
$mysqli->next_result();
echo $output_value;
Now you are ready to execute a second stored procedure without having the "Commands out of sync, you can't run the command now" error. If you were returning more than one value in the record set you can loop through and fetch all of them like this:
while ($stmt->fetch()) {
echo $output_value;
}
If you are returning more than one record set from the stored proc (you have multiple selects), then make sure to go through all of those record sets by using $stmt->next_result();

Another connection within the try

Good afternoon everyone, I have a doubt.
I have a SELECT with PDO. More must be done within another SELECT WHILE to get data for that select, giving it more
Error (Error: There Is Already an active transaction).
If anyone can help me be grateful.
Example code.
try{
$this->conex->beginTransaction();
$query = $this->conex->prepare("SELECT idUser FROM usuario WHERE id = :id ORDER BY data DESC LIMIT $pagin, $paginaF");
$query->bindParam(":id", $ID, PDO::PARAM_INT, 20);
$query->execute();
while ($lista = $query->fetch()){
$idUser = $lista['idUser'];
echo "<div id='avatar'>"box::avatar($idUser)."</div>"
}
//Here he works out of WHILE. Inside it does not work...
echo box::avatar($idUser);
$this->conex->commit();
}catch (PDOException $ex) {
echo "Erro: " . $ex->getMessage();
}
public function avatar($idUser){
$idUser = (int) $idUser;
$query = $this->conex->prepare("SELECT avatar FROM login WHERE id = :id LIMIT 1");
$query->bindParam(":id", $idUser, PDO::PARAM_INT, 20);
$query->execute();
while ($avatar = $query->fetch()){
$avatar = $avatar['avatar'];
}
return $avatar;
}
You have to close the cursor before calling for a new transaction.
Besides, may I ask why are you creating transactions since you're only doing simple *select*s?
Nested Transactions are not possible (as mentioned by the error message). In the first line, you start one transaction. Within the loop, you call avatar(), that starts another transaction, which fails, because there is already one.
However, for SELECT-Queries you dont need transactions at all. Just omit it.
You may also think about JOIN, so you can handle all in just one Query (and then transactions are really useless).
May not be an answer to the problem for now but this line :
echo "<div id="avatar">".$box = box::avatar($id)."</div>"
is full of errors.
" aren't escaped.
no ; at the end.
You're trying to give a value to a variable inside an echo. This'll throw an error.
If you don't use the avatar() function elsewhere, you can do :
try{
$this->conex->beginTransaction();
$query = $this->conex->prepare("SELECT usuario.id as id, login.avatar as avatar FROM usuario, login WHERE usuario.id = :id and usuario.id ORDER BY data DESC LIMIT $pagin, $paginaF");
$query->bindParam(":id", $ID, PDO::PARAM_INT, 20);
$query->execute();
while ($lista = $query->fetch()){
$id = $lista['id'];
$avatar = $lista['avatar']
echo '<div id="avatar">'.$avatar.'</div>';
}
}catch (PDOException $ex) {
echo "Erro: " . $ex->getMessage();
}

Categories