Foreach in foreach [PHP] - php

Actually I work with PHP framework Codeigniter and I want to compare value from first foreach to second one, but I'm getting an error. Example here:
<?php foreach($posts->result() as $post): ?>
(html content)
<?php foreach($tags->result() as $tag) {
if($tag->id_users == $post->id_users) echo $tag->tag_name;
} ?>
(html content)
<?php endforeach; ?>
When I compare $post->id_users inner second foreach I'm getting error, how can I get around this?

Its better to avoid loop inside a loop
$tag_ids = array();
foreach($tags->result() as $tag) {
$tag_ids[] = $tag->id_users;
}
foreach ($posts->result() as $key => $post) {
if(in_array($post->id_users, $tag_ids)) {
}
}

You don't close the second foreach. For eg
<?php foreach($posts->result() as $post): ?> foreach1
(...some html)
<?php foreach($tags->result() as $tag) { if($tag->id_users == $post->id_users) echo $tag->tag_name; } ?> //foreach2
(...some html)
<?php endforeach; ?>
<?php endforeach; ?>

You should not use $posts->result() and $tags->result() inside foreach loop. Because it will go to check for every time while foreach is live.
Overall it decrease the performance of script.
<?php
$posts = $posts->result();
$tags = $tags->result();
foreach($posts as $post) {
?>
<< Other HTML code goes here >>
<?php
foreach($tags as $tag) {
if($tag->id_users == $post->id_users) {
echo $tag->tag_name;
}
?>
<< Other HTML code >>
<?php
}
}

Related

Loop with curly brackets causes wrong output

I created 2 simple examples:
First example:
<?php $arr = array(1,2,3,4,5); ?>
<?php foreach ($arr as $element) ?>
<?php { ?>
<?php echo $element; ?>
<?php } ?>
output:
5 //Is this result wrong?
Second example:
<?php $arr = array(1,2,3,4,5); ?>
<?php foreach ($arr as $element) { ?>
<?php echo $element; ?>
<?php } ?>
output:
12345
What did I miss about the PHP syntax?
I know that there is an alternative foreach syntax, but in my opinion both shown examples should result in the same output. (Code tested with PHP version: 5.6.12)
Edit:
I know the tags are not needed in every line.
To be more precise: I want to know why the two examples give me 2 different results?
Based on the output, my guess is that:
<?php $arr = array(1,2,3,4,5); ?>
<?php foreach ($arr as $element) ?>
<?php { ?>
<?php echo $element; ?>
<?php } ?>
is being interpreted as:
<?php
$arr = array(1,2,3,4,5);
foreach ($arr as $element);
{
echo $element;
}
?>
Looks like a bug in the interpreter? See comments by Rizier123:
Not a bug: stackoverflow.com/q/29284075/3933332
The brackets after the foreach()/Do nothing here/; is just a statement-group: php.net/manual/en/control-structures.intro.php
Anyways, the code looks atrocious with the way you have written it. Please opt for cleaner code.
Reading through the comments under the question I think Jon Stirling explain this symptom the best:
Just guessing, but perhaps the ?> in the first example is actually being taken as the statement end (loops can be used without braces). At that point, the loop has happened and $element is the last value. Then the braces are just take as a code block which you echo, which is 5.
Over using <? php> is your problem.
You are completing the foreach context before outputting the result and not doing that in the second.
Look at your examples carefully and you should see what you are doing differently.
I don't know why you use so many php tags, but that's why it doesn't work!
try this:
<?php $arr = array(1,2,3,4,5);
foreach ($arr as $element)
{
echo $element;
} ?>
You don't need to use <?php and ?> every single line simply do:
<?php
$arr = array(1,2,3,4,5);
foreach ($arr as $element) {
echo $element;
}
?>
Or alternative syntax:
<?php
$arr = array(1,2,3,4,5);
foreach ($arr as $element)
{
echo $element;
}
?>
Or
<?php
$arr = array(1,2,3,4,5);
foreach ($arr as $element):
echo $element;
endforeach;
?>
When you are doing this:
<?php foreach ($arr as $element) ?>
<?php { ?>
<?php echo $element; ?>
<?php } ?>
PHP loops nothing because it sees
foreach ($arr as $element)
{
}
echo $element;

SimpleXml foreach : ignore element

<?php
$xml = "<articles>
<article id=\"18357302\">
<articleCategories>
<articleCategory id=\"default\"/>
<articleCategory id=\"66607\"/>
</articleCategories>
</article>
</articles>";
$feed = simplexml_load_string($xml);
$items = $feed->article;
foreach ($items as $article) {
// $categorie = $article->articleCategories->articleCategory[id];
$categories = $article->articleCategories;
print_r($categories);
echo "<br>print_r indeed returns an array, but impossible to echo it using foreach!!!<br>";
foreach ($categories->id as $category) {
if ($category != "default") {
echo $category;
}
}
}
?>
not sure what i am doing wrong, i am just trying to find a way to remove the part with the default value inside articlesCategories
<articleCategory id=\"default\"/>
The script needs to ignore this part and just use the next articleCategory from the XML file, and i would prefer to avoid removing it with regex
The script iterates over articleCategories tag.
But it needs to iterate over articleCategory tag.
The following changes will be enough.
foreach ($categories->articleCategory as $category) {
if ($category["id"] != "default") {
echo $category["id"];
}
}

group php foreach loop (Closed) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
How can i group php foreach?i'v already tried 5 days,but still can't get it work
i don't know php foreach how it works, but I'm learning it,
Thanks to everyone's advice
original php:
<?php if(isset($this->leading) && count($this->leading)): ?>
<?php foreach($this->leading as $key=>$item): ?>
<?php
$this->item=$item;
echo $this->loadTemplate('item');
?>
<?php endforeach; ?>
<?php endif; ?>
<?php if(isset($this->primary) && count($this->primary)): ?>
<?php foreach($this->primary as $key=>$item): ?>
<?php
$this->item=$item;
echo $this->loadTemplate('item');
?>
<?php endforeach; ?>
<?php endif; ?>
<?php if(isset($this->secondary) && count($this->secondary)): ?>
<?php foreach($this->secondary as $key=>$item): ?>
<?php
$this->item=$item;
echo $this->loadTemplate('item');
?>
<?php endforeach; ?>
<?php endif; ?>
i tried
<?php if(isset($this->leading) && count($this->leading)) && (isset($this->primary) && count($this->primary)) && (isset($this->secondary) && count($this->secondary)): ?>
<!-- Leading items -->
<?php foreach (array($this->leading, $this->primary, $this->secondary) as $key=>$item) ($this->leading as $key=>$item): ?>
<?php
// Load category_item.php by default
$this->item=$item;
echo $this->loadTemplate('item');
?>
<?php endforeach; ?>
<?php endif; ?>
but not work
As always, your assistance is appreciated!
Thanks!every one:)
Thanks,Steven!
do you mean something like this..?
<?php
$arr = array();
$arr[] = $this->leading;
$arr[] = $this->primary;
$arr[] = $this->secondary;
foreach($arr as $v) {
if(is_array($v) && (count($v) > 0)) {
foreach($v as $item) {
$this->item=$item;
echo $this->loadTemplate('item');
}
}
}
?>
Define a function like:
function foobar ($tmp) {
if(isset($tmp) && count($tmp)) {
foreach ($tmp as $key => $item) {
// Load category_item.php by default
$this->item = $item;
echo $this->loadTemplate('item');
}
}
}
and call it with your data:
foobar($this->leading);
foobar($this->primary);
foobar($this->secondary);
The simplest way to handle this is to first build a list containing all the items you need, and then use just one foreach to cycle through that list.
I'd also recommend some consistancy in whether the three variables (leading, primary, secondary) are defined. If you can guarantee that they're set and are arrays - even if they're empty arrays, it can make your code as simple as this:
<?php
$items = array_merge($this->leading, $this->primary, $this->secondary);
foreach ($items as $Item) {
$this->item = $item;
$this->loadTemplate('item');
}
?>
If you really don't know whether the variables are set, and you can't refactor your code elsewhere to change this, you could do this instead:
<?php
$items = array();
if (isset($this->leading)) $items = array_merge($items, $this->leading);
if (isset($this->primary)) $items = array_merge($items, $this->primary);
if (isset($this->secondary)) $items = array_merge($items, $this->secondary);
foreach ($items as $Item) {
$this->item = $item;
$this->loadTemplate('item');
}
?>

Matching up two foreach loops using array value

I have two foreach loops. The first grabs a load of questions from Wordpress, the second is supposed to grab the multiple answers. This is straight forward had it not involved some randomisation of the questions, which makes it confusing.
This is the two foreach loops without them being randomised.
<?php
$repeater = get_field('step_by_step_test');
foreach( $repeater as $repeater_row ){ ?>
<p><?php echo $repeater_row['question']; ?></p>
<?php $rows = $repeater_row['answer_options'];
foreach ($rows as $row){ ?>
<?php echo $row['answer']; ?><br />
<?php } ?>
<?php } ?>
This loops through each question and also grabs the multiple answers.
How can I incorporate it randomising the questions? This is my attempt, this works for getting a random set of questions but I'm getting an error for the answers part (invalid argument supplied for foreach).
<?php
$amount = get_field('select_number_of_questions');
$repeater = get_field('step_by_step_test');
$random_rows = array_rand( $repeater, $amount );
echo implode(', ', $random_rows);
foreach( $random_rows as $repeater_row ){ ?>
<p><?php echo $repeater[$repeater_row]['question']; ?></p>
<?php $rows = get_sub_field('answer_options');
foreach ($rows as $row){ ?>
<?php echo $row['answer']; ?><br />
<?php } ?>
<?php } ?>
I use this plugin for wordpress - http://www.advancedcustomfields.com/
First I'm going to rewrite your first code block to not look like chewed cud.
<?php
$repeater = get_field("step_by_step_test");
foreach($repeater as $repeater_row) {
echo "<p>".$repeater_row['question']."</p>";
$rows = $repeater_row['answer_options'];
foreach($rows as $row) {
echo $row['answer']."<br />";
}
}
?>
And now for the magic: Add shuffle($rows) immediately before the foreach($rows as $row) { line, and the answers will appear in random order.
EDIT in response to comments: Start your code like this:
$repeater = get_field("step_by_step_test");
shuffle($repeater);
$repeater_limit = array_slice($repeater,0,5);
foreach($repeater_limit as $repeater_row) {
....

php foreach : each link in separate variable

I get some links from feed with this code on simplepie :
if ($check) :
foreach ($feed->get_items(0,3) as $item):
$links = $item->get_permalink();
echo $links;
endforeach; endif;
thats result me:
http://link1....
http://link2....
http://link3....
i want to put each link in separate variable like :
$links1 = 'http://link1....';
$links1 = 'http://link2....';
$links1 = 'http://link3....';
thanks , mori
$i = 0;
foreach($feed->get_items(0,3) as $item)) {
${'link' . ++$i} = $item->get_permalink();
}
Maybe what you want is array variable?
try this:
if ($check) :
foreach ($feed->get_items(0,3) as $item):
$links[] = $item->get_permalink();
endforeach; endif;
if ($check) :
$i=0;
foreach ($feed->get_items(0,3) as $item):
$links.$i = $item->get_permalink();
echo $links.$i;
$i++;
endforeach; endif;
I think it may works...

Categories