Try adding this
@php break; @endphp
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
I and new to PHP and Laravel and I think I am missing something basic. I have a foreach:
@foreach($features as $feature)
@if( $feature->MapNum == $map->MapNum )
{{ $feature->FeNum }} {{ $feature->FullFeType }}
<br />
@endif
@endforeach
So it loops through all the items and when it finds a match it shows the information. But if there isn't a matching number I just want to state it isn't available. Right now if I do that it repeats the message a bunch of times.
Thanks, Stan
Try adding this
@php break; @endphp
@Snapey Ah cool :) Dont work much with blade :p
But a better solution and one I would recommend, is to find the feature in the controller, and just pass it from there
'mapFeature' => $features->filter(fn($item) => $item->MapNum == $map->MapNum)->first(),
@sinnbeck I can break it but I want to show a message. That doesn't seem to allow me to do that.
@stanhook If none are found? Yeah thats why you should filter in the controller. Then you can do an if/else
@Sinnbeck Okay, thanks. I will have to figure that out. Right now this is what I have:
$featuresDataSql = "SELECT DISTINCT trelMapFe.Site, trelMapFe.MapNum, trelMapFe.SUNum,
CASE
WHEN tblFeature.HRONum IS NULL THEN tlkpFeTyp.FeTyp
WHEN tblFeature.HRONum IS NOT NULL THEN
CONCAT(tlkpFeTyp.FeTyp, ' ', tblFeature.HRONum)
END AS FullFeType,
trelMapFe.FeNum
FROM tlkpFeTyp
INNER JOIN (tblFeature
INNER JOIN (tblMap
INNER JOIN trelMapFe ON (trelMapFe.Site = tblMap.Site)
AND (tblMap.MapNum = trelMapFe.MapNum))
ON (tblFeature.FeNum = trelMapFe.FeNum)
AND (tblFeature.SUNum = trelMapFe.SUNum)
AND (tblFeature.Site = trelMapFe.Site))
ON tlkpFeTyp.FeTypCode = tblFeature.FeTypCode
WHERE tblMap.Site LIKE :id $mapNumFe AND tblMap.MapElec = 'True'
ORDER BY trelMapFe.FeNum";
$featuresDataSql = DB::getPdo()->prepare($featuresDataSql);
$featuresDataSql->setFetchMode(\PDO::FETCH_OBJ);
$featuresDataSql->execute([
'id' => $id,
]);
$features = collect($featuresDataSql->fetchAll());
Can you point to docs that can help?
@stanhook I would recommend you start by learning how laravel works. :) No need to use raw pdo
But show what your are passing the to view instead :)
@Sinnbeck Thanks. i have been going through tutorials and the docs. There is a long explanation but this is the way I need to do it. We rebuilt a site that was using APS.Net / T-SQL. I have done this 100 times. I just need to stop the foreach if there isn't a matching number and show a message. First time I needed to do this.
Thanks for the help!
@stanhook No worries. I would like to help but I need to see how your are passing data to the view and I bet I can help :)
@Sinnbeck So I posted the query in my controller and then I return it like this:
->with('features', $features)
And then I run the foreach I posted first. Is that what you are talking about?
@stanhook Where does $map come from then ?
@Sinnbeck Oh, sorry. It is a different query and is at the beginning of my content in a foreach.
@foreach( $maps as $map )
<div class="table-container">
<div class="item">
<div class="column-title">
<p>
<a href="qrymapzoom?Filename=maps/{{ $map->Site }}/Map{{ $map->MapNum }}.tif&zoom=0.25&Site={{ $map->Site }}&MapNum={{ $map->MapNum }}&MapType={{$formData['view']}}">
Map {{ $map->MapNum }}
</a>
</p>
</div>
<div class="column"><p><strong>{{ $map->MapTitle }}</strong></p></div>
</div>
blah, blah,blah...
Thanks, Stan
@stanhook This would be way easier if you were using eloquent and relationships. Maybe try something like this.
@php
$feature = features->filter(fn($item) => $item->MapNum == $map->MapNum)->first())
@endphp
@if( $feature )
{{ $feature->FeNum }} {{ $feature->FullFeType }}
<br />
@else
None found
@endif
@Sinnbeck I placed that in my foreach and it didn't work. All it does is repeat the same information - the first thing in the array.
In my case there could be multiple maps returned with each map having either none or 1+ features. If there isn't a match I just want to state that there is no data available.
Hi,
As @sinnbeck suggested, you should first check if there are any 'features' or 'maps' then iterate over them in the foreach. Your current logic expects that you ALWAYS have something to iterate over, while you are not sure if that is going to happen, so, as stated, you should check if you actually have something to iterate over, if not - display the message - either check with a count() on the array or filter them.
@Mega_Aleksandar Hi, So I have this:
@if( count($features) != 0 )
@foreach($features as $feature)
@if( $feature->MapNum == $map->MapNum )
{{ $feature->FeNum }} {{ $feature->FullFeType }}
<br />
@endif
@endforeach
@else
Not Available
@endif
And Yes, there will always be Features and possibly many for a particular number, just maybe not for that particular number. Which is why if there isn't a Feature I want to add the 'Not Available' text.
@stanhook. suggest
@forelse($features as $feature)
{{ $feature->FeNum }} {{ $feature->FullFeType }}
@if( $feature->MapNum != $map->MapNum )
Not Available
@endif
<br />
@empty
No Features
@endforelse
You should tell the user which entry is not found rather than just abruptly terminating the loop, but I don't know what $map is. Is it another list? Do you need to see if map contains feature?
@stanhook Since you are already doing a with('features') it might be a good idea to check that count and pass the identifier of features or maps that currently do not have that available (aka, a prop with 'noFeaturesYet'=>[{ids of maps that dont have features}]; and then in the foreach check the mapid before checking the feature->mapNum and map->mapNum. I am just throwing ideas...
@stanhook are you doing something else with this Collection that requires you to have potentially many Features passed to the view? If not, then you could modify the query to fetch a single result rather than iterating over the Features Collection.
What is the reason the @sinnbeck suggestion to filter the Collection is not suitable; it does exactly what you need according to your description;?
@tykus So yes, I could have many features. I added some more clarification on a post below.
All filtering the collection did was return and repeat the first result (unless I did it wrong). There could be many different features for this particular map.
@foreach($features as $feature)
@php
$feature = $features->filter(fn($item) => $item->MapNum == $map->MapNum)->first();
@endphp
@if( $feature )
{{ $feature->FeNum }} {{ $feature->FullFeType }} <br />
@else
None found
@endif
@endforeach
If I do it outside I get the same result, the first item only once.
Thank you all for your help and questions. Maybe I should be doing something different.
NOTE: I tried something different in the next post.
I have a site that could have many different maps. When I link is clicked all of the associated maps for that site are shown (using parameters in the URL for the query). Each map has various attributes - title, location, features, associated structures, etc - and each has its own query. Sometimes a map may not have one or more of those attributes.
I run a query at the beginning that gets all of the maps (and map numbers) associated with that site:
@foreach( $maps as $map )
In that foreach are other queries that are run to get all of the other data. Like $features:
$featuresDataSql = "SELECT DISTINCT trelMapFe.Site, trelMapFe.MapNum, trelMapFe.SUNum,
CASE
WHEN tblFeature.HRONum IS NULL THEN tlkpFeTyp.FeTyp
WHEN tblFeature.HRONum IS NOT NULL THEN
CONCAT(tlkpFeTyp.FeTyp, ' ', tblFeature.HRONum)
END AS FullFeType,
trelMapFe.FeNum
FROM tlkpFeTyp
INNER JOIN (tblFeature
INNER JOIN (tblMap
INNER JOIN trelMapFe ON (trelMapFe.Site = tblMap.Site)
AND (tblMap.MapNum = trelMapFe.MapNum))
ON (tblFeature.FeNum = trelMapFe.FeNum)
AND (tblFeature.SUNum = trelMapFe.SUNum)
AND (tblFeature.Site = trelMapFe.Site))
ON tlkpFeTyp.FeTypCode = tblFeature.FeTypCode
WHERE tblMap.Site LIKE :id AND trelMapFe.MapNum IN ('" . $mapNumFeDataString . "')"AND tblMap.MapElec = 'True'
ORDER BY trelMapFe.FeNum";
$featuresDataSql = DB::getPdo()->prepare($featuresDataSql);
$featuresDataSql->setFetchMode(\PDO::FETCH_OBJ);
$featuresDataSql->execute([
'id' => $id,
]);
$features = collect($featuresDataSql->fetchAll());
return view(name of view) ->with('features', $features)
I compare trelMapFe.MapNum to the map number in $map to show the features.
In some cases (like $features) I am matching that attribute with a number(s) from $map. When I match that number there could be many results for that attribute that need to be displayed, like the foreach I am asking about.
@if( count($features) != 0 )
@foreach($features as $feature)
@if( $feature->MapNum == $map->MapNum )
{{ $feature->FeNum }} {{ $feature->FullFeType }}
<br />
@endif
@endforeach
@else
Not Available
@endif
Sometimes there may not be any information and I just wanted to show a message that it wasn't available.
Does that help?
@mega_aleksandar So I check in my controller for the maps and pull the features based on the maps being returned. I go over that array in my view. This works except that since some if the maps have features and some don't I can't figure how to show a message for the ones that don't.
I can do this:
@foreach($features as $feature)
@if( $feature->MapNum == $map->MapNum )
{{ $feature->FeNum }} {{ $feature->FullFeType }}
@else
Not Available
@endif
@endforeach
But not available just gets repeated for how many items are in the array.
suggestions?
@stanhook You just literally posted your initial code.
We get that, we understand it. We don't understand what you are trying to do
you are iterating over a set of features and comparing each to the map-->MapNum (a single value)
if $map->mapNum = 'xyz'
and features = 'abc', 'def', 'hij','klm', 'nop' etc then maybe you never find an 'xyz' and it says not available for every try.
@Snapey Yes, I did re-post the code. I changed my controller so now I am only return features (if any) that belong to the map(s) instead of all the features for all the maps. I thought that would make a difference and I was just trying to keep things together, sorry.
There could be many maps retuned for a site. Each map could have no features or 1+.
if $map->mapNum = 'xyz'
and that has 4 features it should show them.
if $map->mapNum = 'pdq'
and it has no features I want to display a message.
Does that help?
@stanhook You should be able to pass to the $map itself a features property, so that you can check if they exist (0 or 1+) and based on that, you can display a message or iterate over them. So you would not even need the if $feature->mapNum == $map->mapNum since you have the features nested under the map.
@Mega_Aleksandar Okay, that sound promising but how would I do that? I started to compare arrays but I don't think that will work.
Keep in mind that $map and $features could have many results.
I tried this but it adds Not Available to each one once. So the ones that have features it also adds Not Available and the ones the don't it shows Not Available.
@if( count($features) != 0 )
@php $noFeature = false; @endphp
@foreach($features as $feature)
@if( $feature->MapNum == $map->MapNum )
{{ $feature->FeNum }} {{ $feature->FullFeType }}<br />
@elseif( $feature->MapNum != $map->MapNum )
@php $noFeature = true; @endphp
@endif
@endforeach
@if($noFeature)
Not Available
@endif
@endif
Keep in mind that $map and $features could have many results.
but you are always testing the same map value?
@Snapey I am not sure I understand your question, sorry. Maybe this will help, here is what I get in my view when I do the query. There are about 50 maps returned:
Map 463
Site: Structure 103
Map Type: Flat
View: grid east
Map shows the following:
Study Unit(s): 100
Feature(s):
4 Bench segment #3
5 Bench segment #1
7 Pilaster #1
10 Hearth
--------------------------
Map 475
Site Structure 125
Map Type: Profile
View: grid east
Comments: Map includes point-located artifacts/samples
PD number(s): 1110
Map shows the following:
Study Unit(s): noncultural
Horizontal Unit(s):
1-x-2-meter grid unit 69N/188E
1-x-2-meter grid unit 69N/188E
------------------
Map 537
Site Structure 102, Stratigraphic Profile
Map Type: Profile
View: grid east
Map shows the following:
Study Unit(s): 500
Horizontal Unit(s):
1-x-1-meter grid unit 92N/166E
Feature(s):
2 Hearth
3 Pit: not further specified
The first has Features and not Horizontal Units. The next one is the opposite. The third has both. If there aren't any Features I want to have a message. does that help?
Please or to participate in this conversation.