Fetch row with pdo and relational database - php

i have a little problem, i have a database with 2 tables, users and comments and i need to print the result with pdo.
if i try this code, everything works great:
$stmt = $dbConnection->prepare("SELECT comment_text, username FROM users, comments WHERE users.user_id = comments.user_id");
$stmt->execute();
$stmt->fetch(PDO::FETCH_ASSOC);
foreach ($stmt as $row) {
echo $row['comment_text'] . "<br>By " . $row['username'] . "<br>";
}
But if i try to add a variable which get the result of fetch i get a totally different result with only 2 rows and only the first letter of the value...
$stmt = $dbConnection->prepare("SELECT comment_text, username FROM users, comments WHERE users.user_id = comments.user_id");
$stmt->execute();
$comment = $stmt->fetch(PDO::FETCH_ASSOC);
foreach ($comment as $row) {
echo $row['comment_text'] . "<br>By " . $row['username'] . "<br>";
}

if i try this code, everything works great:
it is not.
this way you are losing the very first comment. So it should be just
$stmt->execute();
foreach($stmt as $row )
{
echo $row['comment_text']."<br>By ".$row['username']."<br>" ;
}
in case you want to save the result in array, you have to use the appropriate function for that:
$stmt->execute();
$comments = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($comments as $row )
{
echo $row['comment_text']."<br>By ".$row['username']."<br>" ;
}
while fetch() is getting you only one record, fetchAll() is doing what the name suggests

Both your samples aren't functionning properly :
In the first one you loop over every row except the first row, for which you did a fetch, and then did nothing with this first row.
In the second one you loop over every field of the first row, which produce some unexepected output.

Related

keep a queries result array in storage in php

I am conducting a query whereby I am retrieving all rows from a db table where a certain column = 'xx'.
Then I need to store the array retrieved from the result.
Then I need to delete all those rows from the DB, but i still need to access the stored array AFTER carrying out the delete. It might sound a bit strange but this is what I need to do.
So far:
$Get_Appointments = "SELECT *
FROM TempSchedule2
WHERE CreatedBy = 'xx'";
$stmt = mysqli_stmt_init($con);
mysqli_stmt_prepare($stmt, $Get_Appointments);
mysqli_stmt_execute($stmt);
if ($Apts = mysqli_stmt_get_result($stmt)){
$numRows = mysqli_num_rows($Apts);
echo 'numrows is '.$numRows.'<br>';
global $arrayToSave;
$arrayToSave = mysqli_fetch_array($Apts);
while($row=mysqli_fetch_array($Apts)){
//echo 'in the while?';
$scheduleID = $row['scheduleID'];
$DeleteApt_Query = "DELETE FROM tempschedule2 WHERE scheduleID = ?";
$stmt = mysqli_stmt_init($con);
mysqli_stmt_prepare($stmt, $DeleteApt_Query);
mysqli_stmt_bind_param($stmt, "i", $scheduleID);
if (mysqli_stmt_execute($stmt)){
//executed
echo 'deleted';
}
else {
echo 'not deleted because '.mysqli_error($con);
$ErrorForLog = date("Y-m-d") . "\r\n" . mysqli_error($con). "\r\nInfo Attempted to delete apt id : " . $scheduleID. "\r\n\r\n";
error_log($ErrorForLog, 3, "Logs.txt");
}
}
echo 'savedArray here is ';
var_dump($arrayToSave);
What's happening is one row is not deleting for some reason. And then after the loop that executes the delete queries, I am var_dumping the global $arrayToSave (which i hoped was the entire array), and the result is that one element of the array which had not been deleted. So it seems as thought the global array is being modified within the loop? This is the first time I've had to use global in php so I'm probably not using it right.
Try this:
Change $arrayToSave = mysqli_fetch_array($Apts); to $arrayToSave = array();
Then add $arrayToSave[] = $row directly after the start of the while loop.
mysqli_fetch_array grabs the next row and turns it into an array. It doesn't take the whole result set and turn it into an array. That is why you put it in a while statement. That loops through ALL the rows. So loop through and save the results, then run your delete afterward.
$results = array();
while($row = mysqli_fetch_array($apts){
$results[] = $row;
}
//Now Delete
$DeleteApt_Query = "DELETE FROM tempschedule2 WHERE scheduleID = ?";
$stmt = mysqli_stmt_init($con);
mysqli_stmt_prepare($stmt, $DeleteApt_Query);
mysqli_stmt_bind_param($stmt, "i", $scheduleID);
if (mysqli_stmt_execute($stmt)){
//executed
echo 'deleted';
} else {
echo 'not deleted because '.mysqli_error($con);
$ErrorForLog = date("Y-m-d") . "\r\n" . mysqli_error($con). "\r\nInfo Attempted to delete apt id : " . $scheduleID. "\r\n\r\n";
error_log($ErrorForLog, 3, "Logs.txt");
}
Also, you need to be careful running another query while you are still iterating through the result of a previous query. The data from the first query gets wiped out when you run another query.
global is useless in this place, you can safely delete it.
What you do is put the first retrieved row into $arrayToSave and iterate the over the rest of rows. What you probably want to do, is put all $rows into a two-dimensional array with something like $arrayToSave[] = $row; after the beginning of the while loop.
You fetch one row before the loop thereby removing it from the results $Apts:
$arrayToSave = mysqli_fetch_array($Apts);
So $arrayToSave only contains one row and that row is not looped over. You want to remove that and probably do something like this:
while($row=mysqli_fetch_array($Apts)){
$arrayToSave[] = $row;
Alternately use mysqli_fetch_all():
$arrayToSave = mysqli_fetch_all(($Apts);
foreach($arrayToSave as $row) {
//do stuff
}

cannot retrieve indexes correctly mysqli

$search = htmlspecialchars($_GET["s"]);
if(isset($_GET['s'])) {
// id index exists
$wordarray = explode(" ",$search);
$stringsearch = implode('%',$wordarray);
echo $stringsearch;
echo ",";
$result = mysqli_fetch_array($conn->query("SELECT ID FROM table WHERE title LIKE '%$stringsearch%';"));
if (!empty($result)) {
echo sizeof($result);
echo ",";
Database has 3 rows with titles test,pest,nest with corresponding id's 1,2,3. when i request domain.com/?s=est
it echos something like this
est,2,
Now when i checked $result[0] and $result[1], $result[0] echoed 1 and $result[1] didn't echo anything. When I use foreach function, it is taking only value of $result[0]
and $result should be array of all the three indexes.
I cannot find any mistake,
when i type the same command in sql console it works, somebody help me, thanks in advance.
The problem is, if you're expecting multiple rows, then don't do this:
$result = mysqli_fetch_array($conn->query("SELECT ID FROM table WHERE title LIKE '%$stringsearch%';"));
This only fetches the first row, you need to loop it to advance the next pointer and get the next following row set:
$result = $conn->query("SELECT ID FROM table WHERE title LIKE '%$stringsearch%' ");
while($row = $result->fetch_array()) {
echo $row[0] . '<br/>';
// or $row['ID'];
}
Sidenote: Consider using prepared statements instead, since mysqli already supports this.

Iterating over results of PDO query

I want to run a query using PDO, based on data in the URL paramater (yes, I know that this is prone to attacks, but its internal code for a utility).
$user = 'USER';
$pass = 'PASSWORD';
$dsn = 'mysql:dbname=PRODUCTS;host=HOST';
try {
$productDB = new PDO($dsn, $user, $pass);
$productDB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
$msg = 'PDO ERROR' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
die($msg);
}
if(isset($_GET['cat']))
{
$cat = $_GET['cat'];
print "cat = $cat <br>";
$products = $productDB->prepare('SELECT * FROM products WHERE cat_id LIKE ?');
$products->execute(array($cat));
$rows = $products->rowCount();
print "$rows rows returned";
?>
<table border="1">
<tr>
<td>product_id</td>
<td>product_name</td>
</tr>
<?php
foreach ($products->fetchAll() as $row) {
$id = $row['product_id'];
$product_name = $row['product_name'];
print "<tr>";
print "<th scope=\"row\"><b>$id</b></th>";
print "<td> $product_name </td>";
print "<tr>";
}
print "</table>";
}
?>
When I run this code, it prints the correct number of rows depending on the query, but does not populate the table.
I have also tried replacing the prepare and execute lines with:
$products = $productDB->query("SELECT * FROM products WHERE cat_id LIKE $cat");
Which returns the correct row count, but doesn't otherwise help.
And finally, I've tried replacing the foreach line with something like:
$rows = $products->fetchAll();
foreach ($rows as $row) {
My attempts to do the same with a fixed query all work fine, but I am having trouble working out how to place a variable element in a query, and then iterate over the results.
You're not doing anything to store the result:
$products->execute(array($cat));
needs to go in a variable:
$result = $products->execute(array($cat));
Then, instead of calling $products->fetchAll(), use $results->fetchAll():
foreach ($result->fetchAll() as $row)
I find it easier to use a $query variable (for prepare, etc) and then get the result into something like $result or $product. Makes the code a bit easier to read.
Try this (If I understood correctly) :
$products = $productDB->prepare("SELECT * FROM products WHERE cat_id LIKE :cat");
// Now, you can either do this :
$products->bindParam('cat', '%'.$cat.'%');
$products->execute();
// or you can call execute with an associative array of your parameterized query.
$products->execute(array('cat' => '%'.$cat.'%'));
// Then, get all the results like this :
$rows = $products->fetchAll();
foreach ($rows as $row) {
// Do work here ..
}
// Or, like this :
while ($row = $products->fetch(PDO::FETCH_ASSOC)) {
// Do work here ..
}
I personaly prefer the while, because you don't fetch the whole query in one var, reducing the amount of memory needed.
I also recommend you to use the FETCH_* parameter, to get only the kind of array you want.
By the way, you need to know that rowCount should not be used to count the rows returned by a SELECT. As said by php.net :
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.

Loop results PDO PHP

I'm trying to fetch all records from my table on my site, I have the following
$sth = $conn->prepare("SELECT * FROM directory WHERE user_active != ''");
$sth->execute();
/* Exercise PDOStatement::fetch styles */
$result = $sth->fetch(PDO::FETCH_ASSOC);
foreach ($sth->fetchAll(PDO::FETCH_ASSOC) as $result) {
echo $result[First_Name];
}
Only its not returning all records, only my first, Can anybody see where I'm going wrong?
You need to use a loop:
while ($result = $sth->fetch(PDO::FETCH_ASSOC)) {
echo $result[First_Name];
echo ' ' . $result[Surname];
}
Or you could use fetchAll method:
foreach ($sth->fetchAll(PDO::FETCH_ASSOC) as $result) {
echo $result[First_Name];
echo ' ' . $result[Surname];
}
And Note: If First_Name and Surname are not constants, then you should use the string as the key name.
$result['First_Name'] and $result['Surname']
Well, you only call $sth->fetch once. You need to loop over the results.
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
echo $row['First_Name'] . ' ' . $row['Surname'] . "\n";
}
Also don't call array string indexes without braces. This way PHP checks if the key is a CONSTANT, then casts it to string. This is just bad practice and might lead to unexpected bahavior.
If this returns only one row, you probably have only one row in the database (or the result set). Show us more code!

How do I loop through a PHP array containing data returned from MySQL?

Ok I have a table with a few fields. One of the fields is username. There are many times where the username is the same, for example:
username: bob
password: bob
report: 1
username: bob
password: bob
report: 2
I did a SQL statement to select * where username='bob'; but when I do the following PHP function, it will only return the last result:
$thisrow = mysql_fetch_row($result);
I need to get every field from every row. How should I go about doing this?
$mainsection="auth"; //The name of the table
$query1="select * from auth where username='$user'";
$result = mysql_db_query($dbname, $query1) or die("Failed Query of " . $query1); //do the query
$thisrow=mysql_fetch_row($result);
echo "Study: " . $thisrow[1] . " - " . $thisrow[5];
Sorry for such a dumb question. I can't seem to get the while loops of more than one field working for the life of me.
mysql_fetch_row fetches each row one at a time. In order to retrieve multiple rows, you would use a while loop like this:
while ($row = mysql_fetch_row($result))
{
// code
}
Use a loop, and use mysql_fetch_array() instead of row:
while($row = mysql_fetch_array($result)) {
echo "Study: " . $row[1] . " - " . $row[5];
// but now with mysql_fetch_array() you can do this instead of the above
// line (substitute userID and username with actual database column names)...
echo "Study: " . $row["userID"] . " - " . $row["username"];
}
I suggest you to read this:
http://www.w3schools.com/php/php_mysql_select.asp
It will give you an overview idea of how to properly connect to mysql, gather data etc
For your question, you should use a loop:
while ($row = mysql_fetch_row($result)){//code}
As said by htw
You can also obtain a count of all rows in a table like this:
$count = mysql_fetch_array(mysql_query("SELECT COUNT(*) AS count FROM table"));
$count = $count["count"];
You can also append a normal WHERE clause to the select above and only count rows which match a certain condition (if needed). Then you can use your count for loops:
$data = mysql_query("SELECT * WHERE username='bob'");
for ($i = 0; $i
Also, mysql_fetch_array() is usually a lot easier to use as it stores data in an associative array, so you can access data with the name of the row, rather than it's numeric index.
Edit:
There's some kind of bug or something going on where my second code block isn't showing everything once it's posted. It shows fine on the preview.
I like to separate the DB logic from the display. I generally put my results into an array that I can call within the HTML code. Purely personal preference; but here's how'd I'd approach the problem: (I'd take the $sql out of the error message in production)
<?php
$sql="
SELECT *
FROM auth
WHERE username='$user';
";
$result = mysql_query($sql)
or die("Failed Query : ".mysql_error() . $sql); //do the query
while ($ROW = mysql_fetch_array($result,MYSQL_ASSOC)) {
$USERS[] = $ROW;
}
?>
HTML CODE
<? foreach ($USERS as $USER) { ?>
Study: <?=$USER['dbFieldName'];?> - <?=$USER['dbFieldName2'];?>
<? } //foreach $USER ?>
$qry=mysql_query(select * where username='bob');
if(mysql_num_rows($qry))
{
while($row=mysql_fetch_array($qry,MSQL_NUM))
{
echo $row[0]." ".$row[1]." ".$row[2]."<br>";
}
}

Categories