У меня есть таблица в базе данных, которая содержит различные пути к страницам моего сайта. Каждый путь указан только один раз. В настоящее время у меня есть очень длинная и запутанная серия запросов и PHP, чтобы вытащить все это и переписать данные в неупорядоченный список (чтобы создать меню для моего сайта). Кажется, что, возможно, существует относительно простой циклический подход, который бы работал НАМНОГО более эффективно, но я не могу заставить что-либо работать. Я нашел TONS PHP-скриптов, которые создают списки UL из файловых деревьев, но все они либо не работают, либо не могут справиться с нерекурсивным характером результатов моих запросов (для некоторых требуются многомерные массивы моих путей, которые было бы хорошо, за исключением моей проблемы с созданием тех). Я нашел скрипт, который работает довольно близко, но он неправильно форматирует часть <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, но я столкнулся с проблемой. Оказывается, что сценарий, который я нашел, создает неправильно отформатированные списки 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>';