PHP how to handle when there is no foreach loop? - php

I have a foreach loop that runs perfectly without flaw.
foreach ($row AS $row) {
echo $row['id'];
}
There are times that there are no rows returned. I want to echo out 'there are no rows'; when there are no rows. The problem is if I try to do something like as follows:
foreach ($row AS $row) {
if (!isset($row['id'])) {
echo 'there are no rows';
} else {
echo $row['id'];
}
}
It never returns the echo "there are no rows". I assume this is because when there are no rows, the foreach loop doesn't run. The question becomes, how do I echo "there are no rows" if and only if there are no rows while not interfering with the foreach when there are rows.
I have also tried code such as:
$row1 = $stmt->fetch();
$row = $stmt->fetchAll();
if (isset($row1['id'])) {
foreach ($row AS $row) {
Still no luck
So the desired outcome would be something as follows:
When loop runs:
1
2
3
4
When loop doesn't run:
there are no rows

you should check before the loop like so
if(count($row)>0){
//foreach ...
}else{
echo 'no data';
}

Test if the array is empty:
if (empty($row)) {
echo "there are no rows";
} else {
foreach($row as $row) {
...
}
}

Related

Filtering an array with foreach and for loop

I'm pulling data from mssql database into an array called
$results2
I need to echo out each 'Item' only one time, so this example should only echo out:
"52PTC84C25" and "0118SGUANN-R"
I can do this easily with:
$uniqueItems = array_unique(array_map(function ($i) { return $i['ITEM']; }, $results2));
The issue is when i try to echo out the other items associated with those values. I'm not sure how to even begin on echoing this data. I've tried:
foreach($uniquePids as $items)
{
echo $items."<br />";
foreach($results2 as $row)
{
echo $row['STK_ROOM']."-".$row['BIN']."<br />";
}
}
This returns close to what I need, but not exactly:
This is what I need:
Assuming your resultset is ordered by ITEM...
$item = null; // set non-matching default value
foreach ($results2 as $row) {
if($row['ITEM'] != $item) {
echo "{$row['ITEM']}<br>"; // only echo first occurrence
}
echo "{$row['STK_ROOM']}-{$row['BIN']}<br>";
$item = $row['ITEM']; // update temp variable
}
The if condition in the code will check if the ITEM has already been printed or not.
$ary = array();
foreach($results2 as $row)
{
if(!in_array($row['ITEM'], $ary))
{
echo $row['STK_ROOM']."-".$row['BIN']."<br />";
$ary[] = $row['ITEM'];
}
}

Trying to iterate over a mongodb cursor twice - failing

I am executing a query against my mongodb database... and then in two separate spots in my front end logic, I need to iterate through the results to extract / show different information.
Problem
The second time I try to iterate through, I get the following error message:
Fatal error: Uncaught MongoDB\Driver\Exception\LogicException: Cursors
cannot yield multiple iterators in
/var/www/localhost/htdocs/widgets/exception_details.php:46
Stack trace: #0
Backend Code
Here's the logic to query the database in my model:
try{
$id = new \MongoDB\BSON\ObjectId($docid);
$filter = ['_id' => $id];
$options = [];
$query = new \MongoDB\Driver\Query($filter, $options);
$rows = $m->executeQuery('widgets.play_summary', $query);
return $rows;
} catch (Exception $e) {
echo 'Exception:'. $e->getMessage();
return false;
}
Front End Logic
Here's the logic that attempts the iteration.
First time:
foreach ($rows as $id=>$value) {
if ( count($value->unreachable_servers > 0) ) {
foreach($value->unreachable_servers as $key=>$value) {
echo "<tr>";
echo "<td>$value</td>";
echo "</tr>";
}
}
}
And then later, I try to do this:
$it = new IteratorIterator($rows); //line 46
$it->rewind();
foreach ($rows as $id=>$value) {
if ( count($value->failed_plays > 0) ) {
foreach($value->failed_plays as $key=>$value) {
echo "<tr>";
echo "<td>$value</td>";
echo "</tr>";
}
}
}
Additional Information
Commenting out the following lines gives the exact same error, but just on line 48 instead of line 46:
$it = new IteratorIterator($rows);
$it->rewind();
Any tips would be appreciated.
Thanks.
EDIT 1
As a test, I changed the front end code to use rewind and next like this:
$it = new \IteratorIterator($rows);
$it->rewind();
//foreach ($rows as $id=>$value) {
while($value = $it->current()) {
if ( count($value->unreachable_servers > 0) ) {
foreach($value->unreachable_servers as $key=>$value) {
echo "<tr>";
echo "<td>$value</td>";
echo "</tr>";
}
}
$it->next();
}
And for the second loop:
$it = new IteratorIterator($rows);
$it->rewind();
//foreach ($rows as $id=>$value) {
while($value = $it->current()) {
if ( count($value->failed_plays > 0) ) {
foreach($value->failed_plays as $key=>$value) {
echo "<tr>";
echo "<td>$value</td>";
echo "</tr>";
}
}
$it->next();
}
I get the same results. It works the first time but the second time it bombs with the same error message.
Cursor cannot be iterated twice. Fetch it into array, if it fits into memory:
$rows = $m->executeQuery('widgets.play_summary', $query);
return $rows->toArray();
UPDATE
Since the answer still attracts attention 5 years later, there was https://jira.mongodb.org/browse/PHPC-1691 to implement full Iterator interface, not only Traversable.
The implementation does not resolve OPs issue tho.
Technically https://www.php.net/manual/en/class.mongodb-driver-cursor.php does have the rewind method, but it throws an exception Cursors cannot rewind after starting iteration when called after first document was received: https://github.com/mongodb/mongo-php-driver/blob/0960a204b3b60f8a80375abb6390735b95c821f1/src/MongoDB/Cursor.c#L333

How can I re-organize php array of sports

I'm trying to list sport league offerings for intramurals. My current php foreach spits out all the leagues and offerings. Great.
Now I want to only show 1 instance of the sport (course), like "Basketball" and then list the multiple league offerings (offering) in columns.
I can't do another loop based on
if $nt['course'] == "Basketball" because these will change
Not sure if my mssql query needs to change or if I can use another foreach loop?
query
$sql2 = SELECT category
,course
,offering
,Semester
,spots
,registerLink from dbtable WHERE semester like "%Fall 2016%" and category like "%Leagues%" ORDER BY course
$rs= mssql_query ($sql2, $con)
or die("Error!");
$result = array();
if (mssql_num_rows($rs)) {
while ($row = mssql_fetch_assoc($rs)) {
$result[] = $row;
}
}
return $result;
exit();
my foreach loop in view:
<?php
foreach ($data as $nt) {
echo "<div class='col-md-2'>";
echo "<h2><a href='#'>".$nt['course']."</a></h2>";
echo "<h3>".$nt['offering']."</h3>";
echo "<h4>".$nt['Semester']."</h4>";
echo "<p>".$nt['spots']."</p>";
echo "<button>".$nt['registerLink']."</button>";
echo "</div>";
}
So just to clarify:
category = "Leagues" which is in my query
course = Basketball and Flag Football, etc
It's very simple:-
instead of
$result[] = $row;
do
$result[ $row['course']][] = $row;
Simple solution:
$result = array();
if (mssql_num_rows($rs)) {
while ($row = mssql_fetch_assoc($rs)) {
if(!in_array($row["course"], $result))
{
array_push($result, $row["course"]);
}
array_push($result[$row["course"]], $row);
}
}
return $result;
And loop in view:
foreach($data as $key => $value)
{
echo "<h1>".$key."</h1>";
foreach($value as $nt)
{
echo "<div class='col-md-2'>";
echo "<h3>".$nt['offering']."</h3>";
echo "<h4>".$nt['Semester']."</h4>";
echo "<p>".$nt['spots']."</p>";
echo "<button>".$nt['registerLink']."</button>";
echo "</div>";
}
}

why are my rows looping 12000 times when they should be looping 170 times?

I am running a while/foreach on a mySQL database and an array to check if it exists or not. It's supposed to loop 170 times but it loops over 12000 times. Why is that?
$my_rows = array();
while($row = mysql_fetch_assoc($run_query)){
$my_rows[] = $row;
foreach($my_rows as $row){
if(in_array_r($row['name'], $products)){
echo "Exists";
} else {
echo "Does not exist";
}
}
}
What should be happening here is that you assign the result of mysql_fetch_assoc to $my_rows and then loop over the contents of $my_rows. One loop. One of those loops doesn't need to exist.
$my_rows = mysql_fetch_assoc(...);
foreach($my_rows as $row){ ...do stuff here... }
$my_rows = array();
while($row = mysql_fetch_assoc($run_query)){
$my_rows[] = $row;
if(in_array_r($row['name'], $products)){
echo "Exists";
} else {
echo "Does not exist";
}
}

output specific array key for each result

i have a search engine for my page. as a result i would like to ouput the array key for each result.
so i have this code:
$results = search($keywords);
$results_num = count($results); //what shows the message how many items were found
if (!empty($errors){
foreach ($results as $result){
echo "this is result: "
.$result['key']; //thought would be the solution, its not.
}
} else {
foreach ($errors as $error){
$error;
}
}
i also tried using a counter like:
$results = search($keywords);
$results_num = count($results); //what shows the message how many items were found
$counter = 0;
if (!empty($errors){
foreach ($results as $result){
$counter++;
echo "this is result: "
.$counter;
}
} else {
foreach ($errors as $error){
$error;
}
}
what doesnt work as i thought and is still not that professional.
so if there is someone who could tell me how to solve this i really would appreciate. thanks a lot.
foreach ($results as $key => $result) {
echo 'this is result: ' . $key;
}
The current key will be assigned to $key and the value for that property will be assigned to $result
http://php.net/manual/en/control-structures.foreach.php
edit
In response to your comments, I think this is what you're trying to achieve:-
$i=0;
foreach($results as $result) {
echo 'this is result: ' . ++$i;
}
foreach($arr as $key=>$val){
//do something with key and value
}
Here in code you can check first if $results array is not empty because sometime due to empty $results array foreach generates error
/*Check if $results array is empty or not*/
if(!empty($results)){
foreach ($results as $key=>$result){
/*result you want to show here according conditions*/
}
}

Categories