How to generate menu from dynamic multidimensional array [closed] - php

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Lets say I have the array down here. I left out a few maps and files as this should be enough to make my point. There is no max depth to the array so there could be even more.
Array
(
[media] => Array
(
[documents] => Array
(
[0] => add.php
)
[music] => Array
(
[albums] => Array
(
[0] => add.php
)
)
[overview] => Array
(
[0] => overview.php
)
)
What I would like to get is something like the following:
<ul>
<li>Media
<ul>
<li>Documents
<ul>
<li>Add</li>
</ul>
</li>
<li>Music
<ul>
<li>Albums
<ul>
<li>Add</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</li>Overview
<ul>
<li>Overview</li>
</ul>
</li>
</ul>
I found php create navigation menu from multidimensional array dynamically but imo the accepted answer has quite a lot garbage and the result isn't quite of what I need. If you would like to know how the array is generated please let me know.
Thanks in advance for helping me

You need to use a recursive function that loops through your array. Something like this:
function outputMenu(array $array, $baseUrl = '/')
{
$html = '';
foreach ($array as $key => $item)
{
if (is_array($item))
{
$html .= '<li>'.$key.'<ul>';
$html .= outputMenu($item, $baseUrl.$key.'/');
$html .= '</ul></li>';
}
else
{
$html .= '<li>'.ucfirst(substr($item, 0, -4)).'</li>';
}
}
return $html;
}
echo outputMenu($array);

$array = array(
'media'=>array('documents'=>array('add.php'),
'music'=>array('albums'=>array('add.php'))),
'overview'=>array('overview.php')
);
print_link($array);
function print_link($arre){
foreach($arre as $key => $arr){
if(is_array($arr)){
echo '<li>'. $key .'<ul>';
print_link($arr);//echo '<li>'.$arr.'</li>';
echo '</ul><li>';
} else {
echo '<li>'.$arr.'</li>';
}
}
}
you will need a function for this for this task

Related

How to search an array in PHP basing on a condition [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
If I have an array like this:
$cars = array (
array("name"=>"jeep","Year"=>"2012"),
array("name"=>"ferrari","Year"=>"2017"),
array("name"=>"jaguar","Year"=>"2013")
);
How to print a $cars['name'] where $cars[Year] = 2013, is that possible in the array as we can do in MySQL? As we know with MySQL we can do:
select * from table where //condition
So, how this can be done in arrays?
You could loop through each element in the array and using an 'if' statement echo the name of the car if the year is 2013
$cars = array (
array("name"=>"jeep","Year"=>"2012"),
array("name"=>"ferrari","Year"=>"2017"),
array("name"=>"jaguar","Year"=>"2013")
);
foreach ($cars as $value) {
if($value[Year] == 2013){
echo $value[name] ."<br>";
}
}
And also solution with array_filter, because you will probably have multiple cars with same year.
$cars = array (
array("name"=>"jeep","Year"=>"2012"),
array("name"=>"ferrari","Year"=>"2017"),
array("name"=>"jaguar","Year"=>"2013")
);
$filtered_cars = array_filter($cars, function ($item) {
return $item['Year'] === '2013';
});
print_r(current($filtered_cars)['name']);
An example with the isFromYear function accepting the year as a parameter:
<?php
$cars = array (
array("name"=>"jeep","Year"=>"2012"),
array("name"=>"ferrari","Year"=>"2017"),
array("name"=>"jaguar","Year"=>"2013")
);
class YearFilter {
private $year;
function __construct($year) {
$this->year = $year;
}
function isFromYear($i) {
return $i["Year"] == $this->year;
}
}
$matches = array_filter($cars, array(new YearFilter("2013"), 'isFromYear'));
print_r($matches);
?>
You can use array_filter() and pass an conditional function as the second argument along with your array. As an example in your case:
function filterArray($value){
if($value['Year'] == "2013")
return $value['name'];
}
$filteredArray = array_filter($fullArray, 'filterArray');
So if we passed an array that looks like:
$fullArray = array (
array("name"=>"John","Year"=>"2012"),
array("name"=>"Doe","Year"=>"2017"),
array("name"=>"Martin","Year"=>"2013")
);
Output would be:
Array
(
[2] => Array
(
[name] => Martin
[Year] => 2013
)
)

Use foreach instead of print_r [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Improve this question
I have a line of code to get attributes :
$attributes = $as->getAttributes();
When i use print_r
$results = print_r($attributes);
This is what i get :
Array
(
[http://schemas.microsoft.com/2012/12/certificatecontext/extension/subjectkeyidentifier] => Array
(
[0] => username
)
[http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress] => Array
(
[0] => email#mail.com
)
[http://schemas.xmlsoap.org/claims/CommonName] => Array
(
[0] => User lastname
)
[http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn] => Array
(
[0] => email#mail.com
)
[uid] => Array
(
[0] => user
)
)
How can i display those results with a foreach ?
To get all the informations you can use
foreach($attributes as $url=>$info)
{
echo $url; //example : http://schemas.microsoft.com/2012/12/certificatecontext/extension/subjectkeyidentifier
foreach($info as $key=>$attr)
{
echo $key; //example : 0
echo $attr; //example : username
}
}
Per your answers to the comments, you want to be able to format each row differently. Therefore, you could do something like the following:
<?php
foreach($attributes as $key => $value){
echo $key; // the key of the array
echo $value; // the value of the array row
echo '<br />'; // if you want a new line
}
However, if you want a common format, such as a list, you could use implode to do it for you (docs).
<?php
echo '<ul><li>'; // Open list and add first open tag
echo implode('</li><li>', $attributes);
echo '</li></ul>'; //Close last item and list element
And this would generate an HTML formatted list of the elements, though you certainly could do any delimiter that worked for your project.

Recursive sitemap array function php

I having some problems generating a full tree of my db(sitemap). I reached a level that i want to write better code. Thats why i choose a recursive function for this puzzle.
I want to generate a endless unordered list.
Like so:
<ul>
<li><a></a>
<ul>
<li><a></a>(subs)
etc etc etc.....
</ul>
</li>
</ul>
Like i already said i tried the following:
<?php
function traverseArray($array, $sub=false)
{
foreach($array as $cat)
{
if(isset($cat['childeren']) && is_array($cat['childeren']))
{
//a category with subs
echo('<ul id="'.$cat['parent_cat_id'].'" class="lv0">');
echo('<li id="'.$cat['parent_cat_id'].'"><a href=#>'.$cat['name'].'</a>'."\n");
traverseArray($cat['childeren'], true);
}else{
if($sub){
//a sub category of category
echo('</ul></li>');
echo('<li id="'.$cat['parent_cat_id'].'"><a href=#>'.$cat['name'].'</a></li>'."\n");
}else{
//category with no subs
echo('<ul id="'.$cat['parent_cat_id'].'" class="lv0">');
echo('<li id="'.$cat['parent_cat_id'].'"><a href=#>'.$cat['name'].'</a></li>'."\n");
echo('</ul>');
}
}
}
}
traverseArray($sitemap);
?>
but this is a puzzle i cant figure out properly,
this the result so far(messy):
<ul id="0" class="lv0">
<li id="0"><a href=#>Headsets</a>
</ul></li>
<li id="1"><a href=#>(USB) headsets ....</a></li>
</ul></li>
<li id="1"><a href=#>... headsets</a></li>
</ul></li>
<li id="1"><a href=#>.. USB headsets</a></li>
</ul></li>
<li id="1"><a href=#>Bluetooth headsets</a></li>
<ul id="0" class="lv0">
<li id="0"><a href=#>Unified Communications</a></li>
A big mess!
The $sitemap array looks like this:
Array
(
[0] => Array
(
[category_id] => 1
[parent_cat_id] => 0
..........etc
........etc
[type] => cat
[childeren] => Array
(
[0] => Array
(
[category_id] => 2
[parent_cat_id] => 1
.......etc
[type] => cat
[childeren] => Array
(
[0] => Array
(
[category_id] => 32
[parent_cat_id] => 16
.......etc
[type] => series
)
)
So childeren in childeren in childeren,
Is this the best way to do this/ on the right track?
Or are there beter ways out there?
Like sql tree's or something? or just again the old foreach in foreach ..(which i am trying to avoid this time).
Any help would be much appreciated!!!
Thanks in advance,
Jacob
"What is wrong with my code?" is not a question for stackoverflow.
Think about what 'traverseArray' function should do.
Your code is a mess.
Here is a cleaned example of array traversing.
Please fit it to your needs:
function traverseArray($array)
{
echo '<ul>';
foreach($array as $cat)
{
echo '<li>';
if(isset($cat['childeren']) && is_array($cat['childeren']))
{
echo '' . $cat['name'] . '';
traverseArray($cat['childeren']);
}
else
{
echo '' . $cat['name'] . '';
}
echo '</li>';
}
echo '</ul>';
}
traverseArray($sitemap);

Walking thru HTML in PHP

Here is what I have so far:
My string:
$str = "<ul>
<li><a name="valuehere1" title="titlehere" href="/channel/london/">Link1</a></li>
<li><a name="valuehere2" title="titlehere" href="/channel/games/">Link1</a></li>
<li><a name="valuehere3" title="titlehere" href="/channel/sport/">Link1</a></li>
</ul>";
My PHP so far (and I am stuck):
$dom = new domDocument;
$dom->loadHTML($str);
$children = $dom->getElementsByTagName('li')->item(0)->childNodes->getAttribute('name');
$out = array();
foreach ($children as $child) {
$out[] = $dom->saveXML($child);
}
I am trying to extract the NAME attribute value of the A tag in the LI base on a match (in this example they are "london", "games", "sport") . WHen I pass "games" it should give me the output as "valuehere2". This has to be done at the server side due to some restrictions I have. Can someone help me with this please?
Thanks,
L
You've almost got it. But your code is fetching an attribute of the first li it finds, and tries to use that attribute value as an array to loop on. What you want is:
$children = $dom->getElementsByTagName('li');
$out = array();
foreach ($children as $child) {
if ($child->item(0)->childNodes->getAttribute('name')) {
$out[] = $dom->saveXML($child);
}
}
getElementsByTagName returns an DOMElementList (or whatever), which is an iterable array. Doing the getAttribute() stuff simply returns a string.
Regular expressions to the rescue?
[~]% cat test.php
<?php
$str = '<ul>
<li><a name="valuehere1" title="titlehere" href="/channel/london/">Link1</a></li>
<li><a name="valuehere2" title="titlehere" href="/channel/games/">Link1</a></li>
<li><a name="valuehere3" title="titlehere" href="/channel/sport/">Link1</a></li>
</ul>';
preg_match_all('/<li><a name="(.*)" title/', $str, $m);
print_r($m);
?>
[~]% php test.php
Array
(
[0] => Array
(
[0] => <li><a name="valuehere1" title
[1] => <li><a name="valuehere2" title
[2] => <li><a name="valuehere3" title
)
[1] => Array
(
[0] => valuehere1
[1] => valuehere2
[2] => valuehere3
)
)

Array of paths to html lists

I wrote a recursive function, which returns an array with the paths to all files/folders in a given path. An array is already sorted and returns the exact information i want, but i struggle to display it properly in html lists.
Array_of_paths = (
[0] => /path/to/folderA/
[1] => /path/to/folderA/subfolderAA/
[2] => /path/to/folderB/
[3] => /path/to/folderB/subfolderBB/
[4] => /path/to/folderB/subfolderBB/fileBB.txt
[5] => /path/to/folderB/fileB.txt
[6] => /path/to/folderC/
...
)
I want to put these paths in <ul>,<li> tags to see something like this:
<ul>
<li>/path/to/folderA/
<ul>
<li>/path/to/folderA/folderAA/</li>
</ul>
</li>
<li>/path/to/folderB
<ul>
<li>/path/to/folderB/subfolderBB/
<ul>
<li>/path/to/folderB/subfolderBB/fileBB.txt</li>
</ul>
</li>
<li>/path/to/folderB/fileB.txt</li>
</ul>
</li>
<li>/path/to/folderC/</li>
</ul>
=>
<ul>
<li>/path/to/folderA/
<ul>
<li>/path/to/folderA/folderAA/</li>
</ul>
</li>
<li>/path/to/folderB
<ul>
<li>/path/to/folderB/subfolderBB/
<ul>
<li>/path/to/folderB/subfolderBB/fileBB.txt</li>
</ul>
</li>
<li>/path/to/folderB/fileB.txt</li>
</ul>
</li>
<li>/path/to/folderC/</li>
</ul>
I managed to find a couple of similars questions, but the answers were in Ruby language. So, what's the problem solving idea behind this?
$lastD = 0;
foreach ($p as $e)
{
$depth = substr_count($e, '/');
//if this is a file, then add one to the depth count
if (substr($e,-1) != '/')
$depth++;
if ($depth > $lastD)
{
echo "<ul>";
$lastD = $depth;
}
if ($depth < $lastD)
{
echo "</ul>";
$lastD = $depth;
}
echo "<li>$e";
}
Returns:
/path/to/folderA//path/to/folderA/subfolderAA//path/to/folderB//path/to/folderB/subfolderBB//path/to/folderB/subfolderBB/fileBB.txt/path/to/folderB/fileB.txt/path/to/folderC/
If your are in PHP5, use RecursiveDirectoryIterator and RecursiveIteratorIterator to do the job.
$dir = new RecursiveDirectoryIterator("/path");
$it = new RecursiveIteratorIterator($dir);
foreach ($it as $key => $value) {
// Use $it->getDepth() and $value->getRealpath()
// with Byron's code to generate your list
}
I'm using this bit of code you published.
The structure of nested UL's is not quite right, so I just added a quick fix in order to have the closing ul tags so it can be used with more levels.
....
if ($depth < $lastD)
{
$closingULs=$lastD-$depth;
for($i=0;$i<$closingULs;$i++)
{
$uls.="</ul>";
}
echo $uls;
$lastD = $depth;
}
IMHO it's better to store the data in a more efficient and more similar format, something hierarchical. You can explode() your array by / and create the tree via arrays, then it'll be easy to foreach the array and build the HTML list.
foreach ( $paths as $path )
{
$pieces = explode('/', $path);
foreach ( $pieces as $piece )
{
$pathtree[$piece] = '';
}
}
This new $pathtree array is much smaller, probably 1/4th as small as your $paths array. From this point you just need to foreach it to build your HTML list tree.

Categories