我的数据库中有一个表,其中包含我网站页面的各种路径。每条路径仅列出一次。我目前有一系列非常长且复杂的查询和 PHP 来提取所有这些并将数据重写到无序列表中(为我的网站创建菜单)。似乎有一种相对简单的循环方法可以更有效地工作,但我似乎无法让任何东西工作。我发现了大量从文件树创建 UL 列表的 PHP 脚本,但它们要么不起作用,要么无法处理查询结果固有的非递归性质(有些需要路径的多维数组,这会很好,除了我在创建它们时遇到的麻烦)。我确实找到了一个非常接近的脚本,但它格式化了<ul>
通过将子列表放置在外部来错误地部分<li>
部分(我将在下面解释)
这是一个示例:
DB 在结果数组中返回以下内容:
about/contact/
about/contact/form/
about/history/
about/staff/
about/staff/bobjones/
about/staff/sallymae/
products/
products/gifts/
products/widgets/
我想创建以下输出:
<ul>
<li>about/
<ul>
<li>about/contact/
<ul>
<li>about/contact/form/</li>
</ul>
</li>
<li>about/history/</li>
<li>about/staff/
<ul>
<li>about/staff/bobjones/</li>
<li>about/staff/sallymae/</li>
</ul>
</li>
</ul>
</li>
<li>products/
<ul>
<li>products/gifts/</li>
<li>products/widgets/</li>
</ul>
</li>
</ul>
所以我非常接近这里找到的脚本:http://www.daniweb.com/forums/thread285916.html http://www.daniweb.com/forums/thread285916.html但我遇到了一个问题。事实证明,我发现的脚本创建了格式不正确的 UL 列表。在正确的情况下,子列表包含在<li>
父元素的。在此脚本中,父级<li>
被关闭,然后<ul>
块被插入。整个脚本实际上相当优雅,它与关卡等保持同步,但我无法完全理解它来弄清楚如何修复它。我在这里的一个函数中拥有全部内容:
function generateMainMenu()
{
global $db;
$MenuListOutput = '';
$PathsArray = array();
$sql = "SELECT PageUrlName FROM `table`";
$result = mysql_query($sql, $db) or die('MySQL error: ' . mysql_error());
while ($PageDataArray = mysql_fetch_array($result))
{
$PathsArray[] = rtrim($PageDataArray['PageUrlName'],"/"); //this function does not like paths to end in a slash, so remove trailing slash before saving to array
}
sort($PathsArray);// These need to be sorted.
$MenuListOutput .= '<ul id="nav">'."\n";//get things started off right
$directories=array ();
$topmark=0;
$submenu=0;
foreach ($PathsArray as $value) {
// break up each path into it's constituent directories
$limb=explode("/",$value);
for($i=0;$i<count($limb);$i++) {
if ($i+1==count($limb)){
// It's the 'Leaf' of the tree, so it needs a link
if ($topmark>$i){
// the previous path had more directories, therefore more Unordered Lists.
$MenuListOutput .= str_repeat("</ul>",$topmark-$i); // Close off the Unordered Lists
$MenuListOutput .= "\n";// For neatness
}
$MenuListOutput .= '<li><a href="/'.$value.'">'.$limb[$i]."</a></li>\n";// Print the Leaf link
$topmark=$i;// Establish the number of directories in this path
}else{
// It's a directory
if($directories[$i]!=$limb[$i]){
// If the directory is the same as the previous path we are not interested.
if ($topmark>$i){// the previous path had more directories, therefore more Unordered Lists.
$MenuListOutput .= str_repeat("</ul>",$topmark-$i);// Close off the Unordered Lists
$MenuListOutput .= "\n";// For neatness
}
// (next line replaced to avoid duplicate listing of each parent)
//$MenuListOutput .= "<li>".$limb[$i]."</li>\n<ul>\n";
$MenuListOutput .= "<ul>\n";
$submenu++;// Increment the dropdown.
$directories[$i]=$limb[$i];// Mark it so that if the next path's directory in a similar position is the same, it won't be processed.
}
}
}
}
$MenuListOutput .= str_repeat("</ul>",$topmark+1);// Close off the Unordered Lists
return $MenuListOutput."\n\n\n";
}
它返回这样的内容:
<ul id="nav">
<li><a href="/about">about</a></li>
<ul>
<li><a href="/about/history">history</a></li>
<li><a href="/about/job-opportunities">job-opportunities</a></li>
<li><a href="/about/mission">mission</a></li>
<li><a href="/about/privacy-policy">privacy-policy</a></li>
</ul>
<li><a href="/giftcards">giftcards</a></li>
<li><a href="/locations">locations</a></li>
<ul>
<li><a href="/locations/main-office">main-office</a></li>
<li><a href="/locations/branch-office">branch-office</a></li>
</ul>
<li><a href="/packages">packages</a></li>
</ul>
任何人都知道我需要在哪里添加一些额外的逻辑以及如何实现这一点?关于更好的方法的其他想法?看起来这是一个很常见的问题,应该有一个简单/标准的方法来处理这样的事情。也许如果我能弄清楚如何从我的路径创建一个多维数组,那么可以迭代这些数组来完成这项工作?
编辑:更复杂:-(
我尝试了卡萨布兰卡的回应,效果非常好……但我后来意识到,现在我有一个后续行动,让事情变得更加困难。为了显示页面的“名称”,我还需要在数组中包含该信息,因此路径可能会更好地作为数组键和值中的名称。关于这样改变的任何想法:
$paths = array(
"about/contact/ " => "Contact Us",
"about/contact/form/ " => "Contact Form",
"about/history/ " => "Our History",
"about/staff/ " => "Our Staff",
"about/staff/bobjones/ " => "Bob",
"about/staff/sallymae/ " => "Sally",
"products/ " => "All Products",
"products/gifts/ " => "Gift Ideas!",
"products/widgets/ " => "Widgets"
);
然后在buildUL
功能:
echo '<a href="'.$prefix.$key.'/">'.$paths[$prefix.$key].'</a>';