loop through array of objects - php

I Have an array called $pages content is as follows:
Array
(
[01-about-us] => Page Object
(
[_uri] => about-us
[_menuItem] => 01
[_visable] => 1
)
[02-contact] => Page Object
(
[_uri] => contact
[_menuItem] => 02
[_visable] => 1
)
[_sitemap] => Page Object
(
[_uri] => sitemap
[_menuItem] =>
[_visable] =>
)
[home] => Page Object
(
[_uri] => home
[_menuItem] =>
[_visable] => 1
)
)
is there an easy way to loop through and get page objects by there properties ie:
<?php foreach($pages->_visible() AS $p): ?>
<li> page </li>
<?php endforeach ?>

No. You will have to use an if:
foreach ($pages as $page) {
if ($page->_visible == 1) {
echo "<li>page</li>";
}
}
(Note also you misspelt visible in the array, perhaps a typo?)

Or you can utilize PHP's array_filter function:
$pagesVisible = array_filter($pages, function($page) {
return (bool) $page->_visible;
});
foreach ($pagesVisible as $key => $page) {
print '<li>' . $key . '</li>';
}
Or shorthand it to:
$filter = function($page) {
return (bool) $page->_visible;
};
foreach (array_filter($pages, $filter) as $key => $page) {
print '<li>' . $key . '</li>';
}

You just need to loop through the pages array and inside the loop access the object properties like:
<?php foreach($pages as $k => $p): ?>
<?php if ($p->_visable === 1): ?>
<li><?php echo $k; ?></li>
<?php endif; ?>
<?php endforeach; ?>
Please note that visable is misspelled but thats how it is in your question

Related

How to make group (if specific field are same text) in loop?

I tried render data in loop and if extend_tag field have same text group in one container.
I only know hard code like below, loop data base on how many known extend_tag group, but actually the extend_tag numbers is unknown might be tag_ and any digit , any idea how to solve it?
data
[tag] => Array (
[0] => Array (
[id] => 1
[extend_tag] => tag_0
)
[1] => Array (
[id] => 2
[extend_tag] => tag_11
)
[2] => Array (
[id] => 3
[extend_tag] => tag_4
)
)
<ul class="container">
<?php foreach($rows['tag'] as $eachRowsTag) { ?>
<?php if ($eachRowsTag['extend_tag'] == 'tag_0') { ?>
<li>><?php echo $eachRowsTag['id']; ?></li>
<?php } ?>
<?php } ?>
</ul>
<ul class="container">
<?php foreach($rows['tag'] as $eachRowsTag) { ?>
<?php if ($eachRowsTag['extend_tag'] == 'tag_1') { ?>
<li>><?php echo $eachRowsTag['id']; ?></li>
<?php } ?>
<?php } ?>
</ul>
...
Why not group them first, then iterate over the resulting array. Something like the following.
foreach ($tags as $tag) {
$grouped[$tag['extend_tag']][] = $tag;
}
// Now $grouped is something along the lines of:
// [
// 'tag_0' => [
// [ 'id' => 1, 'extend_tag' => 'tag_0'],
// ..
// ],
// ..
// ]
foreach($grouped as $extend_tag => $tags) {
echo "All tags in $extended_tag.";
foreach($tags as $tag) {
echo $tag['id'];
}
}
// For something like:
// All tags in tag_0.
// 1
// 4
// All tags in tag_1.
// ..

iterating over multi dimensional array for a menu

Hello I have a menu made in codeigniter. but I also want this to have submenu's
Therefore I get an array and go through it with a foreach loop.
<ul>
<?php foreach ($menu_item as $menu =>& $key): ?>
<li><?php echo anchor($menu, $key, $this->uri->slash_segment(1, 'leading') == $menu ? 'class="active"' : '') ?></li>
<?php endforeach ?>
</ul>
Now the problem is that this works great if its just one menu without submenu's but when I get an array like this
$menu_item = array(
'/' => 'Home',
'/about' => 'About',
'/foo' => 'boo',
'/contact' => 'contact',
'test' => array(
'foo' => 'boo'
),
'test2' => 'foo2'
);
Than it doesn't work anymore. How can I loop through everything and output it as a good menu?
You can use recursion to do that job. It takes a bit of getting your head around if you're not familiar with it, but it's very well suited to this kind of problem.
I haven't run this code in PHP, but it will give you an idea.
Basically what happens is that the main menu function checks each item to see if it's an array, and then calls the function again using the sub menu. This will work infinitely deep if required.
<?php
$menu = array(
'/' => 'Home',
'/about' => 'About',
'/foo' => 'boo',
'/contact' => 'contact',
'test' => array(
'foo' => 'boo'
),
'test2' => 'foo2'
);
?>
<ul>
<?php showMenu($menu); ?>
</ul>
<?php
function showMenu($menu)
{
<?php foreach ($menu_item as $menu =>& $key): ?>
<li><?php echo anchor($menu, $key, $this->uri->slash_segment(1, 'leading') == $menu ? 'class="active"' : '') ?></li>
if(is_array($menu_item))
{
echo "<ul>";
showMenu($menu_item);
echo "</ul>";
}
<?php endforeach ?>
}
?>
Hope this helps.
The concept of the other answers is true, but they generate invalid DOM structure, so I decided to fix it.
You can make a helper file and put the drawMenu() function inside. So, you'll be able to call the function as much as you need.
$menu = array(
'/' => 'Home',
'/about' => 'About',
'/foo' => 'boo',
'/contact' => 'contact',
'test' => array(
'foo' => 'bar',
'baz' => 'qux'
),
'test2' => 'foo2'
);
function drawMenu($menu)
{
$CI =& get_instance();
$output = '';
foreach ($menu as $key => $value) {
$output .= "<li>";
if (is_array($value)) {
$output .= anchor('#', $key);
$output .= PHP_EOL."<ul>".PHP_EOL;
$output .= drawMenu($value);
$output .= "</ul>".PHP_EOL."</li>".PHP_EOL;
} else {
$output .= anchor($key, $value, $CI->uri->slash_segment(1, 'leading') == $key ? 'class="active"' : '');
$output .= "</li>".PHP_EOL;
}
}
return $output;
}
$html = drawMenu($menu);
echo '<ul>'. $html .'</ul>';
Side-note: Usage PHP_EOL constant is arbitrary, it just makes generated DOM more readable.
Update:
I improved the drawMenu() functionality, now you can add a URL address for the headers of sub-menus:
$menu = array(
'/' => 'Home',
'/about' => 'About',
'/foo' => 'boo',
'/contact' => 'contact',
'test' => array(
'foo' => 'bar'
),
'This is Test2|/url/to/test2' => array(
'baz' => 'qux'
)
);
You can add the URL after | separator.
function drawMenu($menu)
{
$CI =& get_instance();
$output = '';
foreach ($menu as $key => $value) {
$output .= "<li>";
if (is_array($value)) {
if (strpos($key, '|') !== false) {
$param = explode('|', $key);
$output .= anchor($param[1], $param[0]);
} else {
$output .= anchor('#', $key);
}
$output .= PHP_EOL."<ul>".PHP_EOL;
$output .= drawMenu($value);
$output .= "</ul>".PHP_EOL."</li>".PHP_EOL;
} else {
$output .= anchor($key, $value, $CI->uri->slash_segment(1, 'leading') == $key ? 'class="active"' : '');
$output .= "</li>".PHP_EOL;
}
}
return $output;
}
You can check if the $key is an array: is_array
Then you can use another foreach to loop through the submenus.
try this
<ul>
<?php function buildmenu($menu_item){ ?>
<?php foreach($menu_item as $item){ ?>
<li><?php echo anchor($menu, $key, $this->uri->slash_segment(1, 'leading') == $menu ? 'class="active"' : '') ?></li>
<?php if(is_array($item)){
buildmenu($item);
} ?>
<?php } ?>
<php} ?>
<?php buildmenu($menu_item) ?>
</ul>
$menu = "<ul>\n";
foreach ($menu_item as $key => $value){
if (is_array($value)){
$menu.= "\t<li>".$key."\n\t\t<ul>\n";
foreach ($value as $key2 => $value2){
$menu .= "\t\t\t<li>".$value2."</li>\n";
}
$menu.= "\t\t</u>\n\t</li>\n";
} else {
$menu .= "\t<li>".$value."</li>\n";
}
}
$menu .= "</ul>";
echo $menu;
Output:
<ul>
<li>Home</li>
<li>About</li>
<li>boo</li>
<li>contact</li>
<li>test
<ul>
<li>boo</li>
</u>
</li>
<li>foo2</li>
</ul>

PHP - How to format this output using given array?

So right now i have an array named $socialMeta, containing:
Array (
[0] => Array (
[socialFacebook] => Array (
[0] => http://www.facebook.com/someUsername
)
)
[1] => Array (
[socialYoutube] => Array (
[0] => http://www.youtube.com/user/someUsername
)
)
[2] => Array (
[socialSoundcloud] => Array (
[0] => http://www.soundcloud.com/someUsername
)
)
)
From this array I need to create the following output:
<div class="social">
Add us on <span>Facebook</span>
Visit us on <span>Youtube</span>
Visit us on <span>Souncloud</span>
</div>
Please not that there are different anchor text for the first link.
For anchor classes i can use $socialMeta key to make whole process a bit easier.
<?php if (!empty($socialMeta)) { ?>
<div class="social">
<?php foreach ($socialMeta as $rows) {?>
<?php foreach ($rows as $key => $val) {?>
<?php
switch ($key) {
case "socialFacebook":
$title = "Facebook";
$class = "fb";
break;
case "socialYoutube":
$title = "Youtube";
$class = "yt";
break;
case "socialSoundcloud":
$title = "Souncloud";
$class = "sc";
break;
}
?>
Add us on <span><?php echo $title; ?></span>
<?php }?>
<?php }?>
</div>
<?php }?>
Start by identifying the network for each element in the array (I assume the name is $array in the following examples):
function add_network($array) {
static $networks = array('Facebook', 'Youtube', 'Soundcloud');
foreach($networks as $network)
if (isset($array['social' . $network])) {
$array['network'] = $network;
return $array;
}
//None found
$array['network'] = false;
return $array;
}
$array = array_map('add_network', $array);
Then transform the array (you should find a better name for this function):
function transform_array($a) {
static $classes = array('Youtube' => 'yt', 'Facebook' => 'fb', 'Soundcloud' => 'sc');
$network = $a['network'];
$class = $classes[$network];
$url = $a['social' . $network][0]
return array('network' => $network,
'url' => $url,
'class' => $class);
}
$array = array_map('transform_array', $array);
And now just loop over the elements of $array:
foreach($array as $row) {
$network = $row['network'];
$url = $row['url'];
$class = $row['class'];
if ($network === 'Facebook')
$link_text = 'Add us on <span>%s</span>';
else
$link_text = 'Visit us on <span>%s</span>'
$link_text = sprintf($link_text, $network);
printf('%s',
$url, $class, $link_text);
}
<?php
function flattenArray(array $input){
$nu = array();
foreach($input as $k => $v){
if(is_array($v) && count($v) == 1){
$nu[key($v)] = current($v);
if(is_array($nu[key($v)]) && count($v) == 1)
$nu[key($v)] = current($nu[key($v)]);
}
else
$nu[$k] = $v;
}
return $nu;
}
// here you can maintain the sortorder of the output and add more social networks with the corresponding URL-text...
$urlData = array(
'socialFacebook' => 'Add us on <span>Facebook></span>',
'socialYoutube' => 'Visit us on <span>Youtube</span>',
'socialSoundcloud' => 'Visit us on <span>Souncloud</span>',
);
$testArray = array(
array('socialFacebook' => array('http.asdfsadf')),
array('socialYoutube' => array('http.asdfsadf')),
array('socialSoundcloud' => array('http.asdfsadf'))
);
$output = flattenArray($testArray);
HERE WE GO
echo '<div class="social">';
foreach($urlData as $network => $linkText){
if(!empty($output[$network]))
echo sprintf('%s</span>', $output[$network], $linkText);
}
echo '</div>';

php create navigation menu from multidimensional array dynamically

I did research on this, and wasn't able to find an exact answer. Most of the questions/answers on here pertaining to this seem to be unfinished. If anyone knows of a finished solution similar to my question, please point me in that direction!
Here is my array:
Array
(
['home'] => Array
(
[0] => sub-home1
[1] => sub-home2
)
['about'] => Array
(
[0] => sub-about
['about2'] => Array
(
[0] => sub-sub-about
)
)
['staff'] => Array
(
[0] => sub-staff1
[1] => sub-staff2
)
['contact'] => contact
)
And here is what I would like to turn it into:
<ul>
<li><a href="">home<a/>
<ul>
<li>sub-home1</li>
<li>sub-home2</li>
</ul>
</li>
<li><a href="">about<a/>
<ul>
<li>sub-about</li>
<li>about2
<ul>
<li><a href="">sub-sub-about<a/></li>
</ul>
</li>
</ul>
</li>
<li><a href="">staff<a/>
<ul>
<li>sub-staff1</li>
<li>sub-staff2</li>
</ul>
</li>
<li><a href="">contact<a/></li>
</ul>
The array will be dynamically generated, but will have a limit of 3 levels ex: about->about2->sub-sub-about. I tried going off of this question: PHP/MySQL Navigation Menu but they didn't really seem to come to a conclusion? I am familiar with foreach's whiles and for loops but I just can't seem to wrap my head around this one.
EDIT: Enzino, your code works!
Here is my solution:
<?php
function MakeMenu($items, $level = 0) {
$ret = "";
$indent = str_repeat(" ", $level * 2);
$ret .= sprintf("%s<ul>\n", $indent);
$indent = str_repeat(" ", ++$level * 2);
foreach ($items as $item => $subitems) {
if (!is_numeric($item)) {
$ret .= sprintf("%s<li><a href=''>%s</a>", $indent, $item);
}
if (is_array($subitems)) {
$ret .= "\n";
$ret .= MakeMenu($subitems, $level + 1);
$ret .= $indent;
} else if (strcmp($item, $subitems)){
$ret .= sprintf("%s<li><a href=''>%s</a>", $indent, $subitems);
}
$ret .= sprintf("</li>\n", $indent);
}
$indent = str_repeat(" ", --$level * 2);
$ret .= sprintf("%s</ul>\n", $indent);
return($ret);
}
$menu = Array(
'home' => Array("sub-home1", "sub-home2"),
'about' => Array("sub-about", "about2" => Array("sub-sub-about")),
'staff' => Array("sub-staff1", "sub-staff2"),
'contact' => "contact"
);
print_r($menu);
echo MakeMenu($menu);
?>
Calvin's solution worked for me. Here's the edited version. We can use more nested loops to get sub - sub menu items.
echo '<ul>';
foreach ($menu as $parent) {
echo '<li>' . $parent . '';
if (is_array($parent)) {
echo '<ul>';
foreach ($parent as $children) {
echo '<li>' . $children . '';
}
echo '</ul>';
}
echo '</li&gt';
}
echo '</ul>';
I think you can use recursion? Here is some pseudocode, not very familiar with php.
function toNavMenu(array A){
for each element in A{
echo "<li>" + element.name + ""
if (element is an array){
echo "<ul>"
toNavMenu(element)
echo "</ul>"
}
echo "</li>"
}
}
I would probably slightly adapt the array to be something like the following:
Array(
0 => Array(
'title' => 'Home',
'children' => Array()
),
1 => Array(
'title' => 'Parent',
'children' => Array(
0 => Array(
'title' => 'Sub 1',
'children' => Array(),
),
1 => Array(
'title' => 'Sub 2',
'children' => Array(
0 => Array(
'title' => 'Sub sub 2-1',
'children' => Array(),
),
),
),
)
)
)
With a structure like this you could use recursion to build your menu HTML:
function buildMenu($menuArray)
{
foreach ($menuArray as $node)
{
echo "<li><a href='#'/>" . $node['title'] . "</a>";
if ( ! empty($node['children'])) {
echo "<ul>";
buildMenu($node['children']);
echo "</ul>";
}
echo "</li>";
}
}

Take an existing array and brake it up by value

I have a simplepie feed that spits out multiple feeds from each of the URL's that are loaded into a a associative array.
This associative array is used to sort the arrays alphabetically using the values.
I'm trying to use that same value sort and keep all of the arrays with the same URL or value together so that when the foreach loop runs I get one div per URL containning all the feeds from that URL for the day
<?php
require_once('php/autoloader.php');
$feed = new SimplePie(); // Create a new instance of SimplePie
// Load the feeds
$urls = array(
'http://abcfamily.go.com/service/feed?id=774372' => 'abc',
'http://animal.discovery.com/news/news.rss' => 'animalplanet',
'http://www.insideaolvideo.com/rss.xml' => 'aolvideo',
'http://feeds.bbci.co.uk/news/world/rss.xml' => 'bbcwn',
'http://www.bing.com' => 'bing',
'http://www.bravotv.com' => 'bravo',
'http://www.cartoonnetwork.com' => 'cartoonnetwork',
'http://feeds.cbsnews.com/CBSNewsMain?format=xml' => 'cbsnews',
'http://www.clicker.com/' => 'clicker',
'http://feeds.feedburner.com/cnet/NnTv?tag=contentBody.1' => 'cnet',
'http://www.comedycentral.com/' => 'comedycentral',
'http://www.crackle.com/' => 'crackle',
'http://www.cwtv.com/feed/episodes/xml' => 'cw',
'http://disney.go.com/disneyxd/' => 'disneyxd',
'http://www.engadget.com/rss.xml' => 'engadget',
'http://syndication.eonline.com/syndication/feeds/rssfeeds/video/index.xml' => 'eonline',
'http://sports.espn.go.com/espn/rss/news' => 'espn',
'http://facebook.com' => 'facebook',
'http://flickr.com/espn/rss/news' => 'flickr',
'http://www.fxnetworks.com//home/tonight_rss.php' => 'fxnetworks',
'http://www.hgtv.com/' => 'hgtv',
'http://www.history.com/this-day-in-history/rss' => 'history',
'http://rss.hulu.com/HuluRecentlyAddedVideos?format=xml' => 'hulu',
'http://rss.imdb.com/daily/born/' => 'imdb',
'http://www.metacafe.com/' => 'metacafe',
'http://feeds.feedburner.com/Monkeyseecom-NewestVideos?format=xml' => 'monkeysee',
'http://pheedo.msnbc.msn.com/id/18424824/device/rss/' => 'msnbc',
'http://www.nationalgeographic.com/' => 'nationalgeographic',
'http://dvd.netflix.com/NewReleasesRSS' => 'netflix',
'http://feeds.nytimes.com/nyt/rss/HomePage' => 'newyorktimes',
'http://www.nick.com/' => 'nickelodeon',
'http://www.nickjr.com/' => 'nickjr',
'http://www.pandora.com/' => 'pandora',
'http://www.pbskids.com/' => 'pbskids',
'http://www.photobucket.com/' => 'photobucket',
'http://feeds.reuters.com/Reuters/worldNews' => 'reuters',
'http://www.revision3.com/' => 'revision3',
'http://www.tbs.com/' => 'tbs',
'http://www.theverge.com/rss/index.xml' => 'theverge',
'http://www.tntdrama.com/' => 'tnt',
'http://www.tvland.com/' => 'tvland',
'http://www.vimeo.com/' => 'vimeo',
'http://www.vudu.com/' => 'vudu',
'http://feeds.wired.com/wired/index?format=xml' => 'wired',
'http://www.xfinitytv.com/' => 'xfinitytv',
'http://www.youtube.com/topic/4qRk91tndwg/most-popular#feed' => 'youtube',
);
$feed->set_feed_url(array_keys($urls));
$feed->enable_cache(true);
$feed->set_cache_location('cache');
$feed->set_cache_duration(1800); // Set the cache time
$feed->set_item_limit(0);
$success = $feed->init(); // Initialize SimplePie
$feed->handle_content_type(); // Take care of the character encoding
?>
<?php require_once("inc/connection.php"); ?>
<?php require_once("inc/functions.php"); ?>
<?php include("inc/header.php"); ?>
<?php
// Sort it
$feed_items = array();
$items = $feed->get_items();
$urls = array_unique($urls);
foreach ($urls as $url => $image) {
$unset = array();
$feed_items[$url] = array();
foreach ($items as $i => $item) {
if ($item->get_feed()->feed_url == $url) {
$feed_items[$url][] = $item;
$unset[] = $i;
}
}
foreach ($unset as $i) {
unset($items[$i]);
}
}
foreach ($feed_items as $feed_url => $items) {
if (empty($items)) {
?>
<div class="item"><img src="images/boreds/<?php echo $urls[$feed_url] ?>.png"/><p>Visit <?php echo $urls[$feed_url] ?> now!</p></div>
<?
continue;
}
$first_item = $items[0];
$feed = $first_item->get_feed();
?>
<?php
$feedCount = 0;
foreach ($items as $item ) {
$feedCount++;
?>
<div class="item"><strong id="amount"><?php echo $feedCount; ?></strong><img src="images/boreds/<?php echo $urls[$feed_url] ?>.png"/><p><?php echo $item->get_title(); ?></p></div>
<?php
}
}
?>
<?php require("inc/footer.php"); ?>
Maybe you can use this one:
$feed = new SimplePie();
$feed->set_feed_url('http://myfirstfeed','http://mysecondfeed');
foreach( $feed->get_items() as $k => $item ) {
echo "<div id='".$k.'">";
echo $item->get_permalink();
echo $title = $item->get_title();
echo $item->get_date('j M Y, g:i a');
echo $item->get_content();
echo "</div>";
}

Categories