İç içe bir ul li oluşturur PHP işlevi?

5 Cevap php

Ben oluşturma bir web sitesine küçük bir CMS eklemek attemptting duyuyorum. Ancak küçük bir sorun rastlamak var. CMS menüler eklemek için PHP fonksiyonları kullanır, bu PHP fonksiyonları HTML oluşturmak. I (TreeMenu) kullanmak istiyorsanız, özellikle fonksiyonu daha sonra bir açılır menü için kullanılabilecek bir iç içe ul li oluşturur. Ancak iç içe ul li bu yüzden gibi yapılandırılmıştır:

<li>Projects (Menu Level 1)</li>
    <ul>
        <li>Project 1 (Menu Level 2)</li>
        <li>Project 2 (Menu Level 2)</li>
        <li>Project 3 (Menu Level 2)</li>
    </ul>
<li>News (Menu Level 1)</li>
<li>Contact (Menu Level 1)</li>

CSS bir açılır menü oluştururken ben Menü Seviye 1 li böylece gibi onun çocuklarını kaydırmak gerektiğine inanıyorum:

<li>Projects (Menu Level 1)
    <ul>
        <li>Project 1 (Menu Level 2)</li>
        <li>Project 2 (Menu Level 2)</li>
        <li>Project 3 (Menu Level 2)</li>
    </ul>
</li>
<li>News (Menu Level 1)</li>
<li>Contact (Menu Level 1)</li>

Ben daha önce PHP ile hiç çalışmamış ve bu nedenle yukarıdaki gerçekleştirmek için işlevini değiştirmek için nasıl bilemeyiz. Ben basit bir değişiklik olacağını umut ediyorum. Aşağıdaki ilk örnek yapısını çıktılar PHP işlevi:

function treemenu($generat=0) {
global $pagenum, $menu, $selected, $extension, $set;
$count=0;
$out="\n";
$intend=0;
while($menu[$count][0] != "") {
	if(strpos($menu[$count][3],"#") === false) {
	if($menu[$count][2]=="0" && $intend==2) {
		$intend--;
		$out.="</ul>\n";
	}
	if($menu[$count][1]=="0" && $intend==1) {
		$intend--;
		$out.="</ul>\n";
	}
	if($menu[$count][1]!="0" && $intend<1) {
		$intend=1;
		$out.="<ul>\n";
	}
	if($menu[$count][2]!="0" && $intend<2) {
		$intend=2;
		$out.="<ul>\n";
	}
	$out.="<li class=\"LNE_menu\"><a ";
	if($menu[$count][4]==$selected['name'])
		$out.= 'class="selected" ';
	if(strpos($menu[$count][3],"*"))
		$out.='href="'.str_replace("*", "",$menu[$count][3]).'">';
	elseif($generat)
		$out.='href="'.$menu[$count][3].".".$set['extension'].'">';
	else
		$out.='href="'.$set['indexfile'].'?page='.$menu[$count][3].'">';
	$out.=$menu[$count][4]."</a></li>\n";
	}
	$count++;
}
return $out;
}

Kimse muhtemelen ikinci örnekte olduğu gibi, hemen sonra ul sarın bir düzey 1 menü öğesinin kapanış li etiketi yapmak için nasıl gibi bana doğru yönde işaret?

5 Cevap

Bu özyineleme kullanımının mükemmel bir örnek olacaktır. (Bunun içinde alt-dizileri ile) bir dizi her düzeyde tanımlar, ve bir işlev işlemek için yeni bir dizi bulduğunda kendisini arayarak, döngüler. Sürece işlevi temizler gibi uygun, bu kadar büyük ölçüde otomatik (</li> & </ol> kapanış).

<?php
// I know which function I'd rather write....
$tree = array('Projects (Menu Level 1)',
              array('Project 1 (Menu Level 2)',
                    'Project 2 (Menu Level 2)',
                    'Project 3 (Menu Level 2)'),
              'News (Menu Level 1)',
              'Contact (Menu Level 1)');

// now quake beneath the power of this fully operational recursive function!
function olLiTree($tree)
{
    echo '<ul>';
    foreach($tree as $item) {
        if (is_array($item)) {
            olLiTree($item);
        } else {
            echo '<li>', $item, '</li>';
        }
    }
    echo '</ul>';
}
olLiTree($tree);  // kick off from the top level

Basit bir fonksiyon tüm ihtiyaç vardır.

function unorderedList($val)
{
    if (is_array($val)) {
    	return '<ul><li>' . 
    			implode('</li><li>', 
    				array_map('unorderedList', $val)) . 
    		'</li></ul>';
    } else {
    	return $val;
    }
}

Test kodu:

$menu = array('Projects (Menu Level 1)',
              array('Project 1 (Menu Level 2)',
                    'Project 2 (Menu Level 2)',
                    'Project 3 (Menu Level 2)'),
              'News (Menu Level 1)',
              'Contact (Menu Level 1)');


echo unorderedList($menu);

Bu Topbit zaten bu beni yendi görünür, ama benimki slightly bu çıkış akışı düz değerini yankı olmadığı farklılık olduğunu, ancak olabilir {[(1)], bir değişkene kaydeder } size kolaylık:

<?php

function GenerateMenu($arr)
{
    $output = "<ul>\n";
    foreach($arr as $val) {
    	if (is_array($val)) {
    		$output .= "<li>\n" . GenerateMenu($val, $output) . "</li>\n";
    	}
    	else {
    		$output .= "<li>" . $val . "</li>\n";
    	}
    }
    $output .= "</ul>\n";
    return $output;
}

$html = GenerateMenu($menu);

?>

Edit:

Teşekkür bamya ve Topbit, şimdi PHP yüklü benim makinede olduğumu, bunu test ettik ve iyi çalışıyor.

Ben bu doğru HTML yapısını verir düşünüyorum.

function GenerateMenu($arr)
{
foreach($arr as $val) {
	if (next($arr)) { $nextitem = current($arr); }
	if (is_array($val)) {
		$output .= "\n<ul>\n" . GenerateMenu($val, $output) . "</ul>\n</li>\n\n";
	}
	elseif (is_array($nextitem)) { $output .= "<li>" . $val; }
	else { $output .= "<li>" . $val . "</li>\n"; }
}
return $output;
}
$html = GenerateMenu($menu);
echo("<ul>\n" . $html . '</ul>');

Aynı test kodu yukarıdaki gibi:

$menu = array('Projects (Menu Level 1)',
          array('Project 1 (Menu Level 2)',
                'Project 2 (Menu Level 2)',
                'Project 3 (Menu Level 2)'),
          'News (Menu Level 1)',
          'Contact (Menu Level 1)');

I wrote this utilizing the PHP DOMDocument class. It will create your list as long and as deep as the list you give it using one simple and easy to follow loop. If you want it organized, just ask your database for the list sorted by title (or whatever) first. It assumes your query object data is contained in $menu_categories and it at least has properties of ->id ->parent_id & ->title (change to your needs)

$dom = new DOMDocument();
$dom->validateOnParse = true;
$dom->loadHTML("<html>");


$root = $dom->createElement('ul');
$root->setAttribute('class', 'menu');
$dom->appendChild($root);


foreach($menu_categories as $count => $category){
    $pid = $category->parent_id;
    $parent = $dom->getElementById('simple-li-'.$pid);

    if($parent != null){

        $ul = $dom->getElementById('simple-ul-'.$pid);

        if($ul == null){
            $ul = $dom->createElement('ul');
            $ul->setAttribute('id', 'simple-ul-'.$pid);
            $parent->appendChild($ul);
        }
        $target = $ul;

    }else{ 
        $target = $root;
    }   

    $li = $dom->createElement('li', $category->title);
    $li->setAttribute('id', 'simple-li-'.$category->id);
    $target->appendChild($li);
}

echo $dom->saveHTML($root);
return;

İşte yorumladı versiyonu ...

/**
 * This is pure and simple PHP!
 * @author Jamin Szczesny - Mar 2014
 * Assuming you have a returned query list of related rows named... 
 *  $menu_categories (the list can be in any order)
 * and it has valid attributes of.. 
 * ->id (category id)
 * ->title  (category title\name)
 * ->parent_id (categories parent)
 * 
 */

$dom = new DOMDocument();//create a document
$dom->validateOnParse = true;//this is a must
$dom->loadHTML("<html>");//you must load some valid html

//add a root list to the dom
$root = $dom->createElement('ul');
$root->setAttribute('class', 'menu');
$dom->appendChild($root);

//loop through all of your category rows
foreach($menu_categories as $count => $category){
    $pid = $category->parent_id;
    $parent = $dom->getElementById('simple-li-'.$pid);

    //see if we found a parent
    if($parent != null){ //parent found...
        //look for a ul within the parent
        $ul = $dom->getElementById('simple-ul-'.$pid);

        //check to see if that ul exists
        if($ul == null){//ul not created yet so create one
            $ul = $dom->createElement('ul');
            $ul->setAttribute('id', 'simple-ul-'.$pid);
            $parent->appendChild($ul);
        }
        $target = $ul;

    }else{ //no parent found...
        $target = $root;
    }   
    //create this list item
    $li = $dom->createElement('li', $category->title);
    $li->setAttribute('id', 'simple-li-'.$category->id);
    $target->appendChild($li);
}
//output only the html from our list
echo $dom->saveHTML($root);
return;