PHP: Dynamische Navigation aus Datei oder SQL laden

KnowSlayes

Cadet 4th Year
Registriert
März 2016
Beiträge
86
Moinsen,

ich betreibe PHP Programmierung als Hobby. Lese mich mehr oder weniger durch Fachbücher und versuche das alles schick zu machen. Naja Versuche es.
Ich möchte eine Modulares System schreiben. Also kleine Module die geladen werden. Ist ein Modul Vorhanden soll es auch ein Navigationseintrag geben.
Also die Navigations soll mehr oder weniger dynamisch sein.
Macht es jetzt mehr Sinn dieses jedes mal aus einer Datenbank zu laden oder ist es schneller eine php Datei einzubinden. Die Module ändern sich ja nicht so oft, da war meine Überlegung nur bei Änderungen die php Datei neu zu schreiben.
Bei der Datenbank Lösung müsste jedes mal die Navigation neu geladen werden.

Es geht wenig um die Geschwindigkeite, sollten mehren Leute das System nutzen.

Vielen Dank für Ihre Meinungen.
 
Deine Module müssten halt eine Eigenschaft active oder so haben und am besten ein Interface implementieren das eine getMenuItem Methode vorschreibt. Die getMenuItem Methode kann entweder einen String oder wenn du Bock drauf hast auch MenuItem Objekt zurückgeben.

Die vorhandenen Module würde ich dann in ein Container oder halt in ein Array packen und an eine View übergeben, die dann das Array oder den Container durchläuft und das Ergebnis der getItemMethode ausgibt. Diese sollte, falls das Modul inaktiv ist, nichts ausgeben.

Hier mal eine Beispiel Implementierung mit einer Presenter Klasse statt View.

PHP:
<?php

interface Module
{
    public function getMenuItem();
}

abstract class AbstractModule implements Module
{
    protected $active;
    protected $menuText;
    
    public function getMenuItem()
    {
        return $this->active ? $this->menuText : '';
    }
}

class ActiveModule extends AbstractModule
{
    protected $active = true;
    protected $menuText = 'Foo';
}

class NonActiveModule extends AbstractModule
{
    protected $active = false;
    protected $menuText = 'Bar';
}

class ModuleContainer
{
    private $modules = [];
    
    public function add(Module $module)
    {
        $this->modules[] = $module;
        return $this;
    }

    /**
     * @return Module[]
     */
    public function getModules()
    {
        return $this->modules;
    }
}

class NavigationPresenter
{
    private $container;
    
    public function __construct(ModuleContainer $container)
    {
        $this->container = $container;
    }
    
    public function display()
    {
        $modules = $this->container->getModules();
        
        foreach ($modules as $module) {
            echo $module->getMenuItem();
        }
    }
}

$container = (new ModuleContainer())->add(new ActiveModule())
    ->add(new NonActiveModule());

(new NavigationPresenter($container))->display();

//erwartete ausgabe: Foo
 
Zuletzt bearbeitet von einem Moderator:
Wozu willst Du denn eine PHP-Datei einbinden? Du hast doch schon eine PHP-Datei, in dieser PHP-Datei kannst Du kleine statische HTML-Schnipsel an der Stelle in die Hauptseite einbinden, an der sie gebraucht werden: navigation-links.htm, navigation-rechts.htm, navigation-top.htm. Und wenn Du damit etwas Übung hast, machst Du aus den statischen HTML-Dateien durch "umbenennen" dynamische Templates: navigation-links.tpl, navigation-rechts.tpl, navigation-top.tpl und lädtst diese dann mit PHP::Smarty an der entsprechenden Stelle auf der Hauptseite. Mit "Datenbank" hat das alles nichts zu tun.
 
Zuletzt bearbeitet: (Rechtschreib)
kling1 schrieb:
Deine Module müssten halt eine Eigenschaft active[...]
Wow. okay, da wäre ich jetzt drauf gekommen. Das war nicht meine Frage. Aber vielen Dank für dieses Anstoß. Der Hilft mir weiter!!!!

@ blöderidiot
Ein Template System nutze ich jetzt schon. Eigenes einfaches Smarty programmiert.

Das Menü soll aus folgenden bestehen:
Modul 1
Modul 2
Modul 3

Wenn ein weiteres Modul programmiert wird oder ein anders entfernt, wollte ich nicht jedes mal den Quellcode zur Navigation anpacken.

Zwei Ideen habe ich.

Idee 1: Die vorhandende Module in einer Datenbank eintragen und jedesmal auslesen wenn die Seite das erstemal aufgerufen wird. Jedes mal ein Datenbank zugriff. Wenn sich ein Modul ändert, hat die Datenbank ändern

Idee 2: Das Menü per einbinden von php, html oder externe Datei einbinden. Wenn sich was ändert, die Datei einmal neu schreiben lassen per script.

Die Frage ist nach der Perfomance. Ist es schneller jedes mal eine Datei einzubinden und das also per Webserver reinzuladen.
Oder jedesmal auf die db zuzugreifen.

(Ich hoffe das ich mich ausdrucken konnte, damit habe ich immer so meine Probleme) :(
 
so eine kleine sql abfrage zwingt jetzt nicht unbedingt einen webserver in knie ;)
natürlich ist es aber ohne db immer schneller
 
Ja eine Anfrage ist klar. Also bei 10.000 Zugriffen, besser per Datei. Richtig verstanden???
 
geht es um 10.000 gleichzeitig? wenn ja dann bietet sich doch auch caching an
 
Zuletzt bearbeitet von einem Moderator:
Was meinst du mit Caching??? Ich vertehe jetzt darunter. Beim ersten Besuch Daten in einer Session Variable cachen
 
Du könntest die Module wenn Sie noch nicht im Cache sind. Aus der Datenbank laden und dann serialisiert in eine Datei speichern. Wenn sie im Cache sind liest du die Datei wieder aus und deserialisierst den Inhalt und schon hast du deine Module ohne Datenbank Zugriff.

Hier ein kleines Beispiel einer Cache Klasse und wie man damit umgeht.

PHP:
<?php

class Cache
{
    protected $path = 'path/to/cache/dir/';

    public function store($key, $value)
    {
        file_put_contents($this->file($key), serialize($value));
    }

    public function retrieve($key)
    {
        return unserialize(file_get_contents($this->file($key)));
    }

    public function has($key)
    {
        return file_exists($this->file($key));
    }

    public function remove($key)
    {
        if ($this->has($key)) {
            unlink($this->file($key));
        }
    }
    
    private function file($key)
    {
        return $this->path . $key . '.cache';
    }
}

$cache = new Cache();

if (!$cache->has('modules')) {
    $modules = load_modules_from_db();
    $cache->store('modules', $modules);
} else {
    $modules = $cache->retrieve('modules');
}
 
Zuletzt bearbeitet von einem Moderator:
Thx, genau so in der richtigung war es gedacht. Ich wollte doch eigentlich nur Denk antöße. Und geliefert bekomme ich was komplette Lösungen.
Hast du in der Ecke Rum liegen oder schreibst du die mal eben schnell selbst??? Egal wie! *Respekt*
 
sind ja keine kompletten lösungen.. sondern nur paar beispiele.. ist halt mein beruf.. und in den jahren in dem ich das nun machen.. hab ich ja auch schon einige probleme lösen dürfen..

ich weiß nicht wie weit dein projekt.. aber wenn es ein rewrite ist oder du etwas neues schreibst und eh noch nicht weit bist.. kann ich dir laravel ans herz legen.. es ist ein intuitives und gut dokumentiertes framework, welches dir sehr viel arbeit abnimmt.. solche sachen wie chaching zum beispeil sind da schon gelöst: https://laravel.com/docs/5.2/cache

https://www.laravel.com/

video tutorials:
https://laracasts.com/series/laravel-5-from-scratch
https://laracasts.com/series/laravel-5-fundamentals
 
Zuletzt bearbeitet von einem Moderator:
Noch viel arbeit vor mir...

Vielen Dank für die Site. Sehr interessant. Das Rad muss ich ja nicht immer neu erfinden.
 
Ich weiß ja nicht wie Deine Module aussehen, ob es nur eine einzelne Dateien oder Ordner sind. Aber Du könntest auch ohne Datenbank checken, welche Dateien/Ordner da sind und damit die Navigation bauen. Das schließt die vorigen Konzepte aber nicht aus. Was wirklich performanter ist, kann ich jetzt so nicht sagen, zur Not müssen das Lasttests oder die Praxis zeigen, wenn Du nicht gleich von 0 auf 100 mit den Zugriffen hochfährst.
 
Vielen Dank für eure Beiträge!
Es waren sehr viele Interessante anregungen die mir auch anderer Stelle geholfen haben.
Nun stehe ich vor ein neuen Problem. Was immer doof ist, wenn nicht weiß wonach man suchen soll.

Und zwar möchte ich am liebsten eine include via Funktion machen. Aber das geht ja nicht, da in der Function include wird.

Ich versuche es mal zu beschreiben:
Es gibt das Module / die Page / und die Action
Action kann drin vorkommen muss aber nicht.
Es gibt eine Funktion die überprüft ob das Module vorhanden und geladen werden kann.
inc_module, inc_page und inc_action sind Funktionen die prüfen ob die Datei vorhanden oder erlaubt ist ein Modul zu laden.

Mein Ansatz
PHP:
include(inc_module(),inc_page());
include(inc_module(),inc_action());
Dabei wird aber zweimal überprüft ob das Module vorhanden

Ich hätte gerne sowas wie
PHP:
inc_load($module,$page,$action);
Und in der Funktion inc_load, sollen dann zwei dateien included werden. Ggf. auch nur eine je nach Abfrage.
 
vll solltest du über ein objektorientierten ansatz nachdenken.. das scheint aj schon etwas komplexeres zu sein.. da wird sowas mit funktionen schnell zum hack
 
Ja, habe ich auch mir so überlegt. Nach dem ich mir das ganze Wochenende nun ein Kopf gemacht habe, habe ich es auch so gemacht.
Es werden nun die beiden include Pfade in einer Klassen erstellt und dann ausgelesen, wenn alle Bedingungen entsprechend sind.

BTW: Ich will es halt verstehen und meine eigene Lösungen finden, vielleicht am Anfang nicht die schönsten aber so lernt man.
Komplett fertige Scripts verbinden möchte ich nicht!
 
ja ist vll erstmal besser so.. also zum üben.. produktiv würde ich trotzdem ein fertiges gestestetes framework nutzen
 
Zurück
Oben