Malcolm Beck´s: Aus einer Funktion eine Klasse machen

Beitrag lesen

مرحبا

<?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