hossi: Problem mit Templateklasse und DB-Abfrage in eigenem CMS

Hallo,

ich bin zurzeit dabei mir ein eigenes kleines CMS zu bauen.
Das CMS soll recht simple gehalten sein, damit auch absolute Laien es benutzen können/sollten :)

Der Aufbau ist wie folgt:
Im Hintergrund steht eine MySQL DB mit folgenden Tabellen:

allgemein_info
      content
      navi
      seo
      subnavi

Ich möcht jetzt auch gar nicht auf alle einzeln eingehen, sondern nur auf die Tabelle "navi", die sieht so aus:

id
name_navi
id_content

ID = ist klar :)
name_navi = Wie der Link / Punkt in der Navigation heißen soll
id_content = die ID des Inhalts (Content). Wird nur zum verklinken bentutzt, zb. index.php?id=ID VOM CONTENT

Alle Daten stehen also somit in einer MySQL-Datenbank.

Da ich das CMS so einfach wie möglich in der späteren Benutzung gestalten will, greife ich auf eine Templateklasse zurück. Die Templates an sich sehen so aus:

  
{include file="header.tpl"}  
<p>  
<a href="index.php?id={$link_navi}">{$name_navi}</a>  
<br>  
{$name_content}<br>  
{$ueberschrift1}<br>  
{$ueberschrift2}<br>  
{$inhalt}<br>  
<br>  
<br>  
{$email}  
{$datenschutz}  
{$datum}  
<p>  
{include file="footer.tpl"}  

Die Daten in der DB werden also von einer PHP-Datei ausgelesen, über die Template-Class werden dann die Inhalte an die Variablen an die Template-Datei (siehe oben) übergeben, damit zum Schluss eine Website dabei rauskommt :)

Jetzt zum eig. Problem:
Ich habe natürlich in der Tabelle "navi" mehrere Einträge bsp. Link1, Link2 usw.

In meiner Ausgabe zum Schluss gibt mir das Template aber nur immer den _letzen_ Eintrag aus der DB aus. Sprich: Wenn ich fünf Links in der Tabelle "navi" stehen habe, erscheint in der Ausgabe zum Schluss immer nur det letzte (fünfte).

Um das ganze veranschaulich zu machen, hier einmal meine index.php:
(Das unwichtige habe ich mal weggelassen..)

  
<?php  
// Benötigte Classen und Configs einlesen  
include("config.php");  
include("template.class.php");  
  
// GET-Variable für db-ID  
$id = $_GET["id"];  
  
// Datenbankabfrage Navigation  
$dbabfrage2 = mysql_query("SELECT * FROM navi WHERE id >= '0'");  
while($result2 = mysql_fetch_assoc($dbabfrage2))  
{  
$name_navi = $result2[name_navi];  
$link_navi = $result2[link_navi];  
}  
  
// Neue Templateinstanz erzeugen  
$tpl = new Template();  
  
// Das Template laden  
if($tpl_wahl == "2")  
  {  
    $tpl->load("content2.tpl");  
  }  
  elseif(tpl_wahl == "3")  
  {  
    $tpl->load("content3.tpl");  
  }  
  else  
  {  
    $tpl->load("content1.tpl");  
  }  
  
// NAVIGATION  
$tpl->assign("name_navi", "$name_navi");  
$tpl->assign("link_navi", "$link_navi");  
  
// Template ausgeben  
$tpl->out();  
?>  

Und hier noch die Template-Klasse: (welche ich über google gefunden habe)

  
<?php  
class Template  
{  
   	/**  
	 * Der Ordner in dem sich die Template-Dateien befinden.  
	 *  
	 * @access public  
	 * @var    string  
	 */  
	protected $templateDir = "html/";  
	  
	/**  
	 * Der Ordner in dem sich die Sprach-Dateien befinden  
	 *  
	 * @access public  
	 * @var    string  
	 */  
	protected $languageDir = "language/";  
	  
	/**  
	 * Der linke Delimter für einen Standard-Platzhalter  
	 *  
	 * @access public  
	 * @var    string  
	 */  
	protected $leftDelimiter = '{$';  
	  
	/**  
	 * Der rechte Delimter für einen Standard-Platzhalter  
	 *  
	 * @access public  
	 * @var    string  
	 */  
	protected $rightDelimiter = '}';  
  
	/**  
	 * Der linke Delimter für eine Funktion  
	 *  
	 * @access public  
	 * @var    string  
	 */  
	protected $leftDelimiterF = '{';  
	  
	/**  
	 * Der rechte Delimter für eine Funktion  
	 *  
	 * @access public  
	 * @var    string  
	 */  
	protected $rightDelimiterF = '}';  
  
	/**  
	 * Der linke Delimter für ein Kommentar  
	 * Sonderzeichen müssen escaped werden, weil der Delimter in einem RegExp  
	 * verwendet wird.  
	 *  
	 * @access public  
	 * @var    string  
	 */  
	protected $leftDelimiterC = '\{\*';  
	  
	/**  
	 * Der rechte Delimter für ein Kommentar  
	 * Sonderzeichen müssen escaped werden, weil der Delimter in einem RegExp  
	 * verwendet wird.  
	 *  
	 * @access public  
	 * @var    string  
	 */  
	protected $rightDelimiterC = '\*\}';  
	  
	/**  
	 * Der linke Delimter für eine Sprachvariable  
	 * Sonderzeichen müssen escaped werden, weil der Delimter in einem RegExp  
	 * verwendet wird.  
	 *  
	 * @access public  
	 * @var    string  
	 */  
	protected $leftDelimiterL = '\{L_';  
	  
	/**  
	 * Der rechte Delimter für eine Sprachvariable  
	 * Sonderzeichen müssen escaped werden, weil der Delimter in einem RegExp  
	 * verwendet wird.  
	 *  
	 * @access public  
	 * @var    string  
	 */  
	protected $rightDelimiterL = '\}';  
	  
  
	/**  
	 * Der komplette Pfad der Templatedatei.  
	 *  
	 * @access protected  
	 * @var    string  
	 */  
	protected $templateFile = "";  
	  
	/**  
	 * Der komplette Pfad der Sprachdatei.  
	 *  
	 * @access protected  
	 * @var    string  
	 */  
	protected $languageFile = "";  
	  
	/**  
	 * Der Dateiname der Templatedatei  
	 *  
	 * @access protected  
	 * @var    string  
	 */  
	protected $templateName = "";  
	  
	/**  
	 * Der Inhalt des Templates.  
	 *  
	 * @access protected  
	 * @var    string  
	 */  
	protected $template = "";  
  
	  
	/**  
	 * Ein paar Eigenschaften ihre Werte zuweisen  
	 *  
	 * @access    public  
	 * @return    boolean  
	 */  
	public function template($tpl_dir = "", $lang_dir = "")  
	{  
		// Template Ordner ändern  
		if (!empty($tpl_dir)) {  
			$this->templateDir = $tpl_dir;  
		}  
  
		// Language Ordner ändern  
		if (!empty($lang_dir)) {  
			$this->languageDir = $lang_dir;  
		}  
		  
		return true;  
	}  
  
	  
	/**  
	 * Die Templatedatei öffnen  
	 *  
	 * @access    public  
	 * @param     string $file Dateiname des Templates  
	 * @return    boolean  
	 */  
	public function load($file)  
	{  
		// Die Eigenschaften zuweisen  
	    $this->templateName = $file;  
		$this->templateFile = $this->templateDir.$file;  
  
		// Wenn ein Dateiname übergeben wurde, versuchen, die Datei zu öffnen  
		if(!empty($this->templateFile)) {  
    		if($fp = @fopen($this->templateFile, "r")) {  
    		    // Den Inhalt des Templates einlesen  
    			$this->template = fread($fp, filesize($this->templateFile));  
    			fclose ($fp);  
    		} else {  
    		    return false;  
    		}  
		}  
  
		// Die methode replaceFuntions() aufrufen  
		$this->replaceFunctions();  
		  
		return true;  
	}  
  
  
	/**  
	 * Die Standard-Platzhalter ersetzen  
	 *  
	 * @access    public  
	 * @param     string $replace      Name of var which should be replaced  
	 * @param     string $replacement  Text with which to replace the var  
	 * @return    boolean  
	 */  
	public function assign($replace, $replacement)  
	{  
		$this->template = str_replace($this->leftDelimiter.$replace.$this->rightDelimiter, $replacement, $this->template);  
		return  true;  
	}  
  
	  
	/**  
	 * Die Sprachdateien öffnen  
	 *  
	 * @access    public  
	 * @param     array $files  Dateinamen der Sprachdateien  
	 * @return    boolean  
	 */  
	public function loadLanguage($files)  
	{  
	    // Die Dateinamen der Sprachdateien  
		$this->languageFiles = $files;  
		  
		// Versuchen, alle Sprachdateien einzubinden  
		for ($i=0;$i<count($this->languageFiles);$i++) {  
		    // wenn die Datei $this->languageDir.$this->languageFiles[$i] nicht existiert  
		    if (!file_exists($this->languageDir.$this->languageFiles[$i])) {  
		        return false;  
		    }  
		    // Einbinden...  
			include($this->languageDir.$this->languageFiles[$i]);  
			// !! jetzt steht das Array $lang zur Verfügung  
		}  
		  
		// Die Sprachvariablen mit dem Text ersetzen  
		$this->replaceLanguage($lang);  
		  
		// $lang zurückgeben, damit $lang auch im PHP-Code verwendet werden kann  
		return $lang;  
	}  
  
	/**  
	 * Replace language vars with text  
	 *  
	 * @param string $lang  
	 */  
	function replaceLanguage($lang)  
	{  
		$this->template = preg_replace("/\{L_(.*)\}/isUe", "\$lang[strtolower('\\1')]", $this->template);  
  
	}  
  
	/**  
	 * Die Funktionen ersetzen  
	 *  
	 * @access    protected  
	 * @return    boolean  
	 */  
	protected function replaceFunctions()  
	{  
	    // Includes ersetzen ( {include file="..."} )  
		while(preg_match("/".$this->leftDelimiterF."include file=\"(.*)\.(.*)\"".$this->rightDelimiterF."/isUe", $this->template)) {  
			$this->template = preg_replace("/".$this->leftDelimiterF."include file=\"(.*)\.(.*)\"".$this->rightDelimiterF."/isUe", "file_get_contents(\$this->templateDir.'\\1'.'.'.'\\2')", $this->template);  
		}  
  
	  
		// Kommentare löschen  
		$this->template = preg_replace("/".$this->leftDelimiterC."(.*)".$this->rightDelimiterC."/isUe", "", $this->template);  
		  
		return  true;  
	}  
	  
  
   	/**  
	 * Das fertige Template ausgeben  
	 *  
	 * @access    public  
	 * @return    boolean  
	 */  
	public function out()  
	{  
        echo $this->template;  
        return true;  
	}  
}  
?>  

Wäre super wenn ihr mir bei meinem Anliegen helfen könntet!

Greetz
hossi

  1. Hi!

    // GET-Variable für db-ID
    $id = $_GET["id"];

    Warum kopierst du den Wert um und greifst nicht direkt darauf zu? Und warum hast du ausgerechnet diese Zeile im geposteten Code gelassen, obwohl nichts davon in selbigem verwendet wird?

    $dbabfrage2 = mysql_query("SELECT * FROM navi WHERE id >= '0'");
    while($result2 = mysql_fetch_assoc($dbabfrage2))

    Berücksichtigst du auch Fehlerzustände, die dir mysql_query() über ihren Rückgabewert mitteilt?

    {
    $name_navi = $result2[name_navi];
    $link_navi = $result2[link_navi];
    }

    Schau dir die while-Schleife mit diesem Inhalt nochmal genau an.

    $tpl->assign("name_navi", "$name_navi");
    $tpl->assign("link_navi", "$link_navi");

    Warum rahmst du Variablen mit String-Begrenzern ein?

    Weder an der Stelle noch in der Template-Klasse achtest du auf die Syntaxregeln der Stelle, an der diese Werte eingefügt werden sollen. Diese Kontextwechsel nicht zu beachten ist einer der häufigsten Programmierfehler. Da die Methode assign() nicht wissen kann, in welchem Kontext die übergebenen Werte letzlich landen, müsste sie so ergänzt werden, dass sie selbst für die zu unterstützenden Systeme (HTML, Javascript, evtl. CSS) die entsprechenden Regeln berücksichtigt (das konkrete System müsste als weiterer Parameter übergeben werden).

    Und hier noch die Template-Klasse: (welche ich über google gefunden habe)

    Die schau ich mir nicht genauer an. Dass sie den Kontextwechsel nicht unterstützt macht sie in meinen Augen schon unbrauchbar. Oder steht wenigstens in ihrer Dokumentation ein großer Hinweis, dass man als Anwender selbst dafür zu sorgen hat, nur du hast ihn ignoriert?

    Das CMS soll recht simple gehalten sein, damit auch absolute Laien es benutzen können/sollten :)

    Was genau soll denn der absolute Laie an dem System noch machen? Darf er die Templates selbst anpassen? Dann kommt auch er mit der Problematik des Kontextwechsels in Berührung, den er nicht ignorieren sollte, wenn ihm sein System und die seiner Besucher lieb sind. Die Alternative wäre, dass er außer reinem Text eintippen gar nichts machen kann. Dann musst du aber nicht einfach nur für die Funktionalität sondern auch für die Sicherheit sorgen.

    Lo!

    1. Hi,

      // GET-Variable für db-ID
      $id = $_GET["id"];

      Warum kopierst du den Wert um und greifst nicht direkt darauf zu? Und warum hast du ausgerechnet diese Zeile im geposteten Code gelassen, obwohl nichts davon in selbigem verwendet wird?

      Habe ich über-sprugen/sehen, sorry dafür.

      $dbabfrage2 = mysql_query("SELECT * FROM navi WHERE id >= '0'");
      while($result2 = mysql_fetch_assoc($dbabfrage2))

      Berücksichtigst du auch Fehlerzustände, die dir mysql_query() über ihren Rückgabewert mitteilt?

      Denke nicht ;) Bei mir kommt kein Fehler, wüsste auch nicht warum :)

      {
      $name_navi = $result2[name_navi];
      $link_navi = $result2[link_navi];
      }

      Schau dir die while-Schleife mit diesem Inhalt nochmal genau an.

      Ok. Ich sehe aber nicht was ich anders machen sollte?!

      $tpl->assign("name_navi", "$name_navi");
      $tpl->assign("link_navi", "$link_navi");

      Warum rahmst du Variablen mit String-Begrenzern ein?

      Wüsste nicht, warum nicht?!

      Das CMS soll recht simple gehalten sein, damit auch absolute Laien es benutzen können/sollten :)

      Was genau soll denn der absolute Laie an dem System noch machen? Darf er die Templates selbst anpassen? Dann kommt auch er mit der Problematik des Kontextwechsels in Berührung, den er nicht ignorieren sollte, wenn ihm sein System und die seiner Besucher lieb sind. Die Alternative wäre, dass er außer reinem Text eintippen gar nichts machen kann. Dann musst du aber nicht einfach nur für die Funktionalität sondern auch für die Sicherheit sorgen.

      Bei sturem Text eintippen, kann aber am Design nicht geändert werden. Und genau das ist der Punkt. Ein funktionielles CMS mit welchem man ohne weiteres einfach seine eigenen Templates verwenden kann, ohne vorher groß irgendwelche Dokus usw. gelesen zu haben.

      Grüße vom immer noch nicht schlauer werdenen

      hossi :)

      1. Hi,

        Berücksichtigst du auch Fehlerzustände, die dir mysql_query() über ihren Rückgabewert mitteilt?

        Denke nicht ;) Bei mir kommt kein Fehler, wüsste auch nicht warum :)

        Momentan bekommst du vielleicht keine - aber wenn irgendwann bspw. die Datenbank mal nicht erreichbar ist o.ä., dann *kann* dein Script gar nicht mehr wie vorgesehen ablaufen. Und darauf sollte das Script reagieren können, bspw. mit einer sinnvollen Fehlermeldung für den Benutzer - und nicht mit unkontrollierten Abbrüchen und ggf. PHP-Fehlermeldungen, mit denen der Benutzer nichts anzufangen weiß.

        Wenn dir noch nicht mal solche Basics der sauberen Programmierung geläufig sind (und du dir noch nicht mal *vorstellen* kannst, welche potentiellen Fehlerquellen es überhaupt geben könnte) - dann ist die Programmierung eines „eigenen CMS“ noch ein paar Nummern zu groß für dich. Fange bitte kleiner an.

        $tpl->assign("name_navi", "$name_navi");
        $tpl->assign("link_navi", "$link_navi");

        Warum rahmst du Variablen mit String-Begrenzern ein?

        Wüsste nicht, warum nicht?!

        Weil es im allgemeinen keinen besonderen Sinn ergibt. Und *wenn* jemand es kommentarlos macht, dann liegt der Verdacht nahe, dass der jenige auch vom Umgang mit den Datentypen noch wenig Ahnung hat.

        {
        $name_navi = $result2[name_navi];
        $link_navi = $result2[link_navi];
        }

        Die beiden Konstanten, die du hier verwendest - hast du die vorher irgendwo definiert?

        Du solltest das error_reporting auf E_ALL und display_errors auf 1 stellen, so lange du entwickelst - dann kann PHP dich auf eine Menge Fehler schon selber hinweisen. Zum sauberen Entwickeln ist das unabdingbar.

        MfG ChrisB

        --
        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
        1. Hi,

          Momentan bekommst du vielleicht keine - aber wenn irgendwann bspw. die Datenbank mal nicht erreichbar ist o.ä., dann *kann* dein Script gar nicht mehr wie vorgesehen ablaufen. Und darauf sollte das Script reagieren können, bspw. mit einer sinnvollen Fehlermeldung für den Benutzer - und nicht mit unkontrollierten Abbrüchen und ggf. PHP-Fehlermeldungen, mit denen der Benutzer nichts anzufangen weiß.

          Sowas steht bei mir in der config.php, bzgl. Verbindugnsproblemen usw. Da würde ich nen Fehler mit sicherheit gemeldet bekommen ;)

          Wenn dir noch nicht mal solche Basics der sauberen Programmierung geläufig sind (und du dir noch nicht mal *vorstellen* kannst, welche potentiellen Fehlerquellen es überhaupt geben könnte) - dann ist die Programmierung eines „eigenen CMS“ noch ein paar Nummern zu groß für dich. Fange bitte kleiner an.

          Wir kommen vom Thema ab.. Ich will das jetzt erstmal für mich zum Laufen bringen.. :)

          $tpl->assign("name_navi", "$name_navi");
          $tpl->assign("link_navi", "$link_navi");

          Warum rahmst du Variablen mit String-Begrenzern ein?

          Wüsste nicht, warum nicht?!

          Weil es im allgemeinen keinen besonderen Sinn ergibt. Und *wenn* jemand es kommentarlos macht, dann liegt der Verdacht nahe, dass der jenige auch vom Umgang mit den Datentypen noch wenig Ahnung hat.

          Ich kanns auch mit [] den Teilen hier machen :) wenn das besser sein sollte.

          {
          $name_navi = $result2[name_navi];
          $link_navi = $result2[link_navi];
          }

          Die beiden Konstanten, die du hier verwendest - hast du die vorher irgendwo definiert?

          Steht in der index.php.

          Du solltest das error_reporting auf E_ALL und display_errors auf 1 stellen, so lange du entwickelst - dann kann PHP dich auf eine Menge Fehler schon selber hinweisen. Zum sauberen Entwickeln ist das unabdingbar.

          Ist an. Bin gerade im xampp. Bekomme aber trozdem keine Fehler ;)

          Greetz
          hossi

      2. Hi!

        while($result2 = mysql_fetch_assoc($dbabfrage2))
        {
        $name_navi = $result2[name_navi];
        $link_navi = $result2[link_navi];
        }
        Schau dir die while-Schleife mit diesem Inhalt nochmal genau an.
        Ok. Ich sehe aber nicht was ich anders machen sollte?!

        Dann erstell eine Kontrollausgabe. Schreib dir beispielsweise vor die schließende Klammer
          echo '$name_navi enthält jetzt: ' . htmlspecialchars($name_navi) . '<br>';
          echo '$link_navi enthält jetzt: ' . htmlspecialchars($link_navi) . '<br>';

        $tpl->assign("name_navi", "$name_navi");
        $tpl->assign("link_navi", "$link_navi");
        Warum rahmst du Variablen mit String-Begrenzern ein?
        Wüsste nicht, warum nicht?!

        Weil sie einfach überflüssig sind. Das Ergebnis des Ausdrucks "$foo" entspricht dem Inhalt der Variablen $foo, nur dass der PHP-Interpreter geringfügig mehr Arbeit hatte, weil er den Variableninhalt nicht direkt verwenden konnte, sondern vorher noch etwas Stringverarbeitung damit treiben musste.

        Das CMS soll recht simple gehalten sein, damit auch absolute Laien es benutzen können/sollten :)
        Was genau soll denn der absolute Laie an dem System noch machen? Darf er die Templates selbst anpassen? [...]
        Bei sturem Text eintippen, kann aber am Design nicht geändert werden. Und genau das ist der Punkt. Ein funktionielles CMS mit welchem man ohne weiteres einfach seine eigenen Templates verwenden kann, ohne vorher groß irgendwelche Dokus usw. gelesen zu haben.

        Und das funktioniert nicht mit absoluten Laien, die keine Ahnung haben, wie man Templates so schreibt, dass am Ende immer noch ein sicheres System entsteht - besonders, wenn ein anscheinend Grade-so-nicht-mehr-Laie das Fundament dazu entwickelt hat. Du brauchst noch eine ganze Menge Erfahrung, bevor du ein System erstellen kannst, das man guten Gewissens an die Öffentlichkeit geben kann. Du solltest ruhig weiterarbeiten, aber nicht mit dem derzeitigen Ziel, es zu veröffentlichen, sondern um dabei zu lernen, wie man sicher programmiert und wo dabei die Fallstricke sind.

        Da geht es übrigens den Menschen wie den Leuten. Vier Studenten schickten sich an, ein Community-System namens Diaspora zu entwickeln. Das hat einige Vorschusslorbeeren für das Konzept bekommen. Doch der vor kurzem veröffentlichte Code zeigte, dass da gravierende Sicherheitslücken drin sind, die nicht einfach nur Ausrutscher sind, sondern zeigen, dass die Fehler systematisch begangen wurden. http://www.kalzumeus.com/2010/09/22/security-lessons-learned-from-the-diaspora-launch/

        Lo!

        1. Hi,

          Dann erstell eine Kontrollausgabe. Schreib dir beispielsweise vor die schließende Klammer
            echo '$name_navi enthält jetzt: ' . htmlspecialchars($name_navi) . '<br>';
            echo '$link_navi enthält jetzt: ' . htmlspecialchars($link_navi) . '<br>';

          meiner Meinung nach ist ein Forum zum Fragen da. Ich verstehe nicht, warum Ihr einem normal-sterblichen nicht eine für jeden verständliche Antwort geben könnt, wenn ihr schon antwortet. Eure Antworten sind mir einfach zu hoch gegriffen, bzw. weis ich nicht was ich damit anstellen soll. Ihr könnt doch nicht erwarten, dass nur weil ihr euch gut mit dieser Materie auskennt, jeder Laie euer Fachchina verstehen muss. Tut mir leid ich tus nicht.

          Und das ist jetzt nicht nur auf diese letzte Anwort hier bezogen, sondern auch allgemein.

          Vielleicht um nochmal zur Sache zurück zu kommen:
          Liegts nun an der Klasse, oder an meiner Abfrage?

          Bin ich auf dem richtigen Weg, wenn ich eine Lösung suche, die mit eine while-schleife und dem mysql_fetch_array zu tun haben?

          Danke.

          Greetz
          hossi

          1. Hi,

            meiner Meinung nach ist ein Forum zum Fragen da. Ich verstehe nicht, warum Ihr einem normal-sterblichen nicht eine für jeden verständliche Antwort geben könnt, wenn ihr schon antwortet. Eure Antworten sind mir einfach zu hoch gegriffen, bzw. weis ich nicht was ich damit anstellen soll. Ihr könnt doch nicht erwarten, dass nur weil ihr euch gut mit dieser Materie auskennt, jeder Laie euer Fachchina verstehen muss. Tut mir leid ich tus nicht.

            Und deshalb weisen wir dich darauf hin, dass du dich erst noch mehr mit den Grundlagen auseinandersetzen solltest bzw. eigentlich musst, bevor du in der Lage bist, dein eigenes CMS zu schreiben - aber das willst du natürlich auch wieder nicht hören.

            dedlfix hat gerade versucht, es dir klar zu machen, und wiederhole es noch mal:

            Ein „CMS“ ist ein komplexes Gebilde.
            So etwas zu erstellen, erfordert mindestens „gute“ Praxis(!)-Kenntnisse in mehreren Bereichen - neben PHP und MySQL (oder was auch immer du zu Datenhaltung einsetzen willst) auch wenigstens noch HTML und HTTP, ggf. auch noch CSS und JavaScript. Kenntnisse/Erfahrungen in der Umsetzung von UIs kommen noch hinzu.

            Grundkenntnisse auf „da hab ich schon mal was mit gemacht“-Level reichen dazu *nicht* aus, wenn du ein komfortabel benutzbares und auch sicheres System erstellen willst.
            Dass es so viele Systeme gibt, die diese Mindestanforderungen nicht erfüllen, liegt daran, dass viele Anfänger deine Einstellung teilen - „alles Fachchinesisch, was ihr schreibt, und ich will doch nur ...“ Auf dieser Basis kann man aber kein hochwertiges Produkt erstellen, sondern nur Bastelware, bei der es schnell vorne und hinten zu krachen beginnen wird.

            Die *Einsicht*, dass es mit „ich will doch nur mal eben ...“ nicht getan ist und dass ein paar Fragen zu winzigen Details in einem Forum nicht ausreichen, die muss erst mal kommen.
            Und anschließend die intensive Beschäftigung mit der Materie - in Eigeninitiative, nicht im Abfeuern von einer Frage, wie sie sich im Verlauf einer Trial&Error-„Programmierung“ ergibt, nach der anderen.

            MfG ChrisB

            --
            RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
          2. Hi!

            Dann erstell eine Kontrollausgabe. Schreib dir beispielsweise vor die schließende Klammer
              echo '$name_navi enthält jetzt: ' . htmlspecialchars($name_navi) . '<br>';
              echo '$link_navi enthält jetzt: ' . htmlspecialchars($link_navi) . '<br>';

            meiner Meinung nach ist ein Forum zum Fragen da. Ich verstehe nicht, warum Ihr einem normal-sterblichen nicht eine für jeden verständliche Antwort geben könnt, wenn ihr schon antwortet. Eure Antworten sind mir einfach zu hoch gegriffen, bzw. weis ich nicht was ich damit anstellen soll. Ihr könnt doch nicht erwarten, dass nur weil ihr euch gut mit dieser Materie auskennt, jeder Laie euer Fachchina verstehen muss. Tut mir leid ich tus nicht.

            Ich versuche dir nicht einfach nur das Ergebnis zu nennen, sondern dir den prinzipiellen Weg dahin zu zeigen. Denn diesen wirst du bei vielen weiteren Problemen ebenfalls gehen müssen. Mit der Kontrollausgabe sollst du den Inhalt der Variablen nach jedem Schleifendurchlauf zu sehen bekommen und dabei erkennen, dass du ihn immer wieder überschreibst. Hast du dir mal die Mühe gemacht, die Kontrollausgabe einzubauen, die ich dir schon verwendungsfähig vorgegeben habe?

            Vielleicht um nochmal zur Sache zurück zu kommen:
            Liegts nun an der Klasse, oder an meiner Abfrage?

            Das herausfinden zu können, gehört zum wichtigsten Handwerkszeug eines Programmierers. Du musst nicht alles bis ins Detail wissen, aber du solltest zumindest einigermaßen wissen, wie man sich an Probleme annähert, wie man Wunsch und Wirklichkeit auf Übereinstimmung prüfen kann.

            Bin ich auf dem richtigen Weg, wenn ich eine Lösung suche, die mit eine while-schleife und dem mysql_fetch_array zu tun haben?

            Zuerst musst du das Problem erkennen, dann kannst du dafür eine Lösung suchen. Du hast nämlich ein prinzipielles Problem eingebaut. Am while-Ende hast du nur noch die Werte eines einzigen Datensatzes und keine Ansammlung in einer für Ansammlungen geeigneten Struktur (Array) und auch im Template ist nicht zu sehen, wie dort die Wiederholung für mehrere Datensätze stattfinden soll. Desweiteren ist in der Klasse kein Mechanismus dafür zu erkennen, denn der müsste ja sinnvollerweise mit einer Schleife arbeiten. Schleifen findet man aber nur bei irgendwas mit Sprachdateien und für Includes. Zudem müsste - wenn dieses Feature vorhanden wäre - auch die Dokumentation erklären, wie man sich wiederholende Teile syntaktisch einbaut.

            Das wäre dann der nächste Punkt, den deine Laien lernen müssten. Erstens zu verstehen, wie aus einem Template-Schnipsel am Ende viele Menüeinträge oder viele Tabellenzeilen oder andere Massendatenauflistungen entstehen. Und zweitens, wie die Syntax dafür zu notieren ist.

            Lo!