مرحبا
<?php /* 22.05.2012 */
$host = '';
$user = '';
$pass = '';
$db = '';
/** .htaccess
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L,QSA]
*/
/**
* Tabellenstruktur für Tabelle `apes_menu`
*/
$drop = 'DROP TABLE IF EXISTS `apes_menu`';
$create = <<<EOT
CREATE TABLE IF NOT EXISTS `apes_menu` (
`itemId` int(8) NOT NULL AUTO_INCREMENT,
`parentId` int(8) DEFAULT "0",
`name` varchar(80),
`href` varchar(80),
PRIMARY KEY (`itemId`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_unicode_ci;
EOT;
/**
* Daten für Tabelle `apes_menu`
*/
~~~~~~sql
$insert = <<<EOT
INSERT INTO `apes_menu` (`itemId`, `parentId`, `name`, `href`) VALUES
(1, 0, 'Startseite', ''),
(2, 0, 'Computer', 'computer'),
(3, 2, 'Hardware', 'hardware'),
(4, 3, 'Mainboard', 'mainboard'),
(5, 3, 'Grakikkarte', 'grafikkarte'),
(6, 4, 'Ram', 'ram'),
(7, 2, 'Software', 'software'),
(8, 7, 'Freeware', 'freeware'),
(9, 7, 'Kostenpflichtig', 'kostenpflichtig'),
(10, 8, 'Bildbearbeitung', 'bildbearbeitung'),
(11, 8, 'Virenschutz', 'virenschutz'),
(12, 8, 'Musik bearbeiten', 'musik-bearbeiten'),
(13, 0, 'Privates', 'privates'),
(14, 13, 'Musik', 'musik'),
(15, 13, 'Bilder', 'bilder'),
(16, 13, 'Videos', 'Videos'),
(17, 16, 'Festival', 'festival'),
(18, 17, '1984', '1984'),
(19, 9, 'Bildbearbeitung', 'bildbearbeitung'),
(20, 9, 'Virenschutz', 'virenschutz'),
(21, 9, 'Musikverwaltung', 'musik-bearbeiten'),
(22, 4, 'Audio', 'audio'),
(23, 4, 'Ethernet', 'ethernet'),
(24, 11, 'Firewall', 'firewall');
EOT;
~~~~~~php
// Verbindung aufbauen
error_reporting(0); // Fehlermeldungen für Verbindungsaufbau unterbinden
$_connect = new mysqli ($host, $user, $pass, $db);
@$_connect->set_charset('utf8');
// Verbindung prüfen
if (mysqli_connect_errno())
exit (printf('<p>Verbindungsaufbau fehlgeschlagen: %s</p>', $_connect->connect_error));
error_reporting(E_ALL | E_STRICT); // Fehlermeldungen wieder aktivieren
// Tabellen löschen und anlegen
if (isset($_GET['create-table'])) {
$_connect->query($create);
$_connect->query($insert);
}
if (isset($_GET['drop-table'])) {
$_connect->query($drop);
}
/**
* $_SERVER['REQUEST_URI'] bearbeiten
*
* Alles zwischen dem ersten relevanten Slash in der Adresszeile und
* dem ersten Fragezeichen ausschneiden und in RequestPath speichern
*
* $_GET['rpath'] wird mittels JQuery gesetzt und wird hier verwendet, damit
* die Links im Ajax-Request korrekt "entlinkt" werden können (s. u.)
*
* @example
* http://example.com/foo/bar/baz?a=1;b=2
* @return "/foo/bar/baz"
*/
define('RequestPath', !empty($_GET['rpath']) ? urldecode($_GET['rpath']) : urldecode(implode('', array_slice(explode('?', $_SERVER['REQUEST_URI']), 0, 1))));
$_URL = explode('/', RequestPath); // RequestPath zerlegen
#print_r ($_URL); // {array(1 => 'foo', 2 => 'bar', 3 => 'baz')}
/**
*
* Das eigentliche Menu-Script
*
* Das Script liest Rekursiv alle Kinder eines Items aus, bis es keine Kinder mehr gibt.
*
* Parameter
@param $_parent ItemId des Elternelements (Root ist immer 0)
@param $_idname <ul id="$_idname"></ul> und in den inneren zweigen <ul id="$_idname_$itemId"></ul>
@param $link Mit diesem Parameter lassen sich Teilzweige kreieren,
dazu übergibt man einfach den Pfad zum Elternzweig
@example
/example
/example/foo
/example/foo/bar
/example/foo/bar/baz
Um jetzt alle Kinder von "/example/foo" anzuzeigen, erwartet das Script einmal die ItemID von "/example/foo" als
Parameter "$_parent" und den URL-ausschnitt "/example/foo" als Parameter "$link".
Dann können alle Kinder von "/example/foo" korrekt angezeigt, und noch wichtiger, richtig verlinkt werden.
Nehmen wir an "/example/foo" hat die itemId "3", dann wäre der Korrekte Funktionsaufruf
MenuList (3, "sub-navigation", "/example/foo", true);
Ergebnis wäre in diesem Fall:
/example/foo/bar
/example/foo/bar/baz
@param $loop Alle Kinder mit deren Kindern anzeigen, Ja oder Nein?!?
@return Valides HTML5
*/
// Statement, dass Rekursiv aufgerufen wird
define('LikeParentId', 'SELECT
itemId, href, name
FROM
apes_menu
WHERE
parentId = %d
ORDER BY
itemId');
function MenuList ($_parent, $_idname, $link=false, $loop=false)
{
global $_connect, $_URL;
$add = $link ? $link : '' ; # Eltern-Link, falls übergeben wird
$li = false; # HTML-Liste
if ($m = $_connect->query(sprintf(LikeParentId, $_connect->real_escape_string($_parent))))
while ($f = $m->fetch_assoc())
{
$link = $add . '/' . urlencode($f['href']); # Link mit etwaigen Eltern
$tree = (strpos('/'.$_URL[1], $link) !== false OR $loop) ? 0 : 1; # Kinder anzeigen?!?
$tmpl = RequestPath != urldecode($link) # Aktive Seite "entlinken"
? '<a data-itemid="%2$d" href="%3$s"%4$s>%1$s</a>' # Link zur Seite
: '<span data-itemid="%2$d" data-href="%3$s"%4$s>%1$s</span>' ; # Aktive Seite ohne Link
$li .= sprintf("\n" . '<li%5$s>' . "$tmpl" . '%6$s</li>' # Liste zusammenbauen
/* 1 */ , $f['name']
/* 2 */ , $f['itemId']
/* 3 */ , $link
/* 4 */ , MenuList ($f['itemId'], 'test') ? ' class="got_childs"' : ''
/* 5 */ , (strpos(RequestPath, urldecode($link)) === 0 AND $link != '/') ? ' class="active_tree"' : ''
/* 6 */ , !$tree ? MenuList ($f['itemId'], "{$_idname}_{$f['itemId']}", $link, 1) : ''
);
}
else # Wenn nichts gefunden wird
return false; # return '<p>Keine Daten gefunden</p>';
# Andernfalls Liste zurückgeben
if ($li)
return sprintf('<!-- %1$s starts --><ul id="%1$s">%2$s</ul><!-- %1$s ends -->', $_idname, $li);
}
/**
* Menu-Script ends
*/
/**
* Das folgende ist ein bisschen Tricky.
* JQuery ruft dieses Script (index.php) mit 3 Parametern auf (?itemid=INT;rpath=STRING;linkto=STRING).
* Wenn diese Seite nun angefordert wird, dann gibt das Script das über
* die Parameter selektierte Menu zurück und beendet die weitere Ausführung, damit im JQuery-Request
* nur das gewünschte Menu drin steht, nicht die Komplette Ausgabe dieses Scriptes.
* Das ist eine Quick&Dirty-Lösung zur veranschaulichung, was sich mit dem Menuscript so anstellen lässt.
*/
if (!empty($_GET['itemid']) AND !empty($_GET['linkto'])) {
if (MenuList ($_GET['itemid'], 'test'))
return printf ('<div id="ajax_request">%1$s</div>'
, MenuList ($_GET['itemid'], 'callback-navigation', urldecode($_GET['linkto']), true));
else
return; // die weitere Ausgabe verhindern
} //
Ausgabe folgt.
mfg