Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > Web Development
You last visited: Today at 11:57

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Dynamisch Methoden von Klassen erweitern

Discussion on Dynamisch Methoden von Klassen erweitern within the Web Development forum part of the Coders Den category.

Reply
 
Old   #1

 
Mr.Tr33's Avatar
 
elite*gold: 2778
Join Date: Feb 2012
Posts: 3,527
Received Thanks: 1,044
Dynamisch Methoden von Klassen erweitern

Hallo,

ich bin mir sicher das Thema wurde bestimmt schon mal irgendwo ausfühlich erklärt, jedoch finde ich hierzu nichts passendes oder ich habe es bis jetzt einfach noch nicht ganz verstanden.

Als Lernzweck habe ich mich an eine CMS rangesetzt die Modular (ob es das richtige Wort dafür ist weiß ich gerade jedoch nicht) funktionieren soll mit dem Ziel, dass ich theoretisch jede einzelne Stelle mit einem weiterem Modul beliebig erweitern kann.
Nun komme ich langsam an meine Grenzen. Ich weiß nicht ob es einfach nur eine Denkblockade ist oder ich noch nicht den richtigen Ansatz gefunden habe.

Hier ein kleines Beispiel, wie es am Ende funktionieren sollte:
Ich habe eine CMS mit einem Menü und Content, jedoch keine Benutzer etc., alles also ganz simpel.
Nun erstellt eine Person (Person A) eine Erweiterung für die CMS. Er möchte Benutzer, Benutzergruppen und Rechte einfügen. Natürlich auch, dass manche Menüpunkte nur dann sichtbar sind, wenn man die passenden Rechte dafür hat. Also erweitert er die Menu Klasse, indem er z.B. bei $menu->isVisible eine weitere Abfrage einfügt ob man die passenden Rechte hat.
Jetzt aber hat eine noch weitere Person (Person B) ebenfalls eine Erweiterung für die CMS geschrieben. Er möchte eine Sortierung für das Menü einbauen. Also erweitert er die Menu Klasse, indem er vor die $menu->display Methode eine Sortiermethode einbaut.

Nun komme ich jedoch zur Denkblockade.
Theoretisch müsste Person A die Klasse Menu extenden. Person B müsste praktisch die Klasse von Person B extenden. Jedoch weiß Person B gar nicht das es eine andere Erweiterung gibt.
Und soweit ich weiß, kann man bei extend keine Variable am Ende ranhängen.

Würde mich über eure Gedanken sehr freuen. Jedoch bitte mehr als 2 Wörter oder nur ein Satz mit dem man nicht viel anfangen kann. Mir wären simple Codeschnipsel am liebsten
Mr.Tr33 is offline  
Old 07/13/2016, 00:03   #2
 
Mikesch01's Avatar
 
elite*gold: 203
Join Date: Sep 2007
Posts: 732
Received Thanks: 190
Eine Denkblockade ist das nicht wirklich. Das ist einfach ein falsches Software-Design. Weder Person A noch Person B sollten die Klasse für das Menü überschreiben, sondern nur Elemente zum Menüpunkt hinzufügen können. Die Verwaltung der Menüpunkte sollte aus deinem CMS heraus erfolgen.

Die Personen können dann mittels bestimmter Schnittstellen (Interface) auf Methoden oder Eigenschaften deines Menü's zugreifen. Eine Sortierung des Menü's sollte von außen nicht möglich sein, da sonst jede Person diese Sortierung ändern könnte.
Mikesch01 is offline  
Old 07/13/2016, 07:14   #3
 
paddelx3's Avatar
 
elite*gold: 0
Join Date: Feb 2012
Posts: 202
Received Thanks: 133
Ich bin zwar müde, aber Versuchs trotzdem mal x)

Erst einmal weiß ich nicht warum deine Klasse Menu die Methode isVisible besitzt. Nach meinen Verständniss kommt diese Funktion erst durch die Erweiterung des Nutzers A hinzu. In seiner reinen Form hätte damit die dazugehörige Tabelle menu die so aussehen könnte:


id href name
1 google.de Google Deutschland
2 elitepvpers.com Elitepvpers
3 golem.de IT Nachrichten

entscheidend sind nur die Felder href und name, aus den sich der Menüpunkt nachher zusammen setzt. Das kannst du bei belieben natürlich noch erweitern. Wenn man nun in unsere Klasse Menu guckt, in Ihren bisherigen Zustand, so besitzt diese die Funktionen display, die die Daten zu den Menüpunkten formatiert, eine Funktion getData um die Daten aus der Tabelle zu bekommen, sowie eine Funktion zum ändern, hinzufügen und löschen. Dementsprechend würde unsere Menu Klasse wie folgt aussehen:

PHP Code:
class Menu 
{
    
// Unser Container für die Daten
    
var $data = array();
    
    
// unsere funktionen zum editieren, löschen und hinzufügen
    
function addMenu()
    {
        
//....
    
}
    function 
deleteMenu()
    {
        
//....
    
}
    function 
editMenu()
    {
        
//....
    
}
    
    
// unsere Funktion um alle Menü Einträge zu erhalten, am besten die ganze Tabelle ins Array übertragen
    
function setData(array $data
    {
       
$this->data $databaseTableArray;
    }
    
    
/**
     * Unsere Funktion zum Anzeigen
     */
    
function display()
    {
        
// Formatiert die Elemente in den $data Array basierend auf den Namen und den Link
        
foreach ($data as $menuEntry)
        {
            echo 
'<li><a href="'$menuEntry['href'].'">'$menuEntry['name'].'</a></li>';
        }
    }

Anstatt nun die Klasse zu extenden, würde ich eher auf ein Hook System bauen so wie es viele große CMS machen. Als beispiel haben wir nun das Plugin, das einen Menüpunkt versteckt. Die Idee ist das die Daten vor der Ausgabe an das Plugin übermittelt werden, diese die Daten bearbeitet und unsere Hauptdaten in $data mit den gelöschten Einträgen ersetzt. Aber kommen wir erst mal zum Hooksystem an sich, ein Nutzer hat auf Stackoverflow ein verdammt gutes Beispiel gegeben: . Nach deinen nöten musst du die Klasse anpassen.



Nun können wir einfach ein Event hinzufügen und diese später vor unserer display Methode auslösen, dazu müssen wir das Event in unseren Quellcode setzen. Und beachten das jedes Plugin die Daten manipuliert, also unseren $data Array ersetzt.

PHP Code:
    function display()
    {
        
// Event Triggern
        
$this->data event('beforeMenuDisplay'$this->data);
        
        
// Formatiert die Elemente in den $data Array basierend auf den Namen und den Link
        
foreach ($data as $menuEntry)
        {
            echo 
'<li><a href="'$menuEntry['href'].'">'$menuEntry['name'].'</a></li>';
        }
    } 
Damit haben wir unsere Basis fertig. Nun simulieren wir das Plugin um bspsw. ein Menüpunkt zu verstecken, ich habe leider keine Zeit um irwas zu testen und auch keine IDE zur Hand.

Gehen wir davon aus das unsere Tabelle nun die ID's beinhaltet, die versteckt werden sollen.

id(id des Menüpunktes)
2

PHP Code:
class PluginMenuHide
{
    
// Unser Container für die Daten
    
var $data = array();
    
    
// unsere Daten aus der Tabelle besorgen
    
function getData()
    {
        
$this->data $databaseTableArray;
    }
    
    
// einträge aus array löschen und array zurückgeben
    
function __construct($menuTableArray)
    {
        
$this->getData();
        
        for (
$i=0;$i<=count($menuTableArray);$i++)
        {
            if(
in_array($menuTableArray[$i], $this->data))
            {
                unset(
$menuTableArray[$i]);
            }
        }
        
        return 
$menuTableArray;
    }

Prinzipiell haben wir unser Plugin, und unser Event, das war wir noch machen müssen ist unser Plugin an das Event zu assoziieren und das bevor das Event aufgerufen wird und nachdem das Plugin geladen wurde.

PHP Code:
event('beforeMenuDisplay'NULL, new PluginMenuHide(array())); 
(Das so zu assoziieren wird nicht klappen, zumal das ein ungültiger Callback ist, wie gesagt bin extremst müde, hoffe aber das dir mein Post in irgend einer Weise geholfen hat. Das wichtigste an den ganzen Post ist im Endeffekt die Event/Hook Klasse des Nutzers auf Stackoverflow. Wenn ich die Tage aus den Urlaub wieder da bin, kann ich das ganze auch so schreiben das es klappt, hab hier wie gesagt keine Möglichkeit Code auszuführen geschweige den ne IDE)
paddelx3 is offline  
Thanks
1 User
Old 07/13/2016, 17:02   #4

 
Mr.Tr33's Avatar
 
elite*gold: 2778
Join Date: Feb 2012
Posts: 3,527
Received Thanks: 1,044
Danke, das hat mir sehr geholfen.

Dafür muss aber die Klasse Menu bearbeitet werden oder nicht?
Somist muss jeder der ein Plugin für das Menü schreibt, die Klasse im Endeffekt bearbeiten.
Mr.Tr33 is offline  
Old 07/13/2016, 18:55   #5
 
paddelx3's Avatar
 
elite*gold: 0
Join Date: Feb 2012
Posts: 202
Received Thanks: 133
Nein muss man nicht. Wenn du mehrere Plugins automatisch lädst und die mehrere Events setzen

PHP Code:
$plugin = new event('beforeMenuDisplay'NULL, new PluginMenuHide(array())); 
PHP Code:
$plugin = new event('beforeMenuDisplay'NULL, new PluginMenuOrder(array())); 
die Idee ist, das all diese Plugins mehrere Events für den Punkt beforeMenuDisplay setzen. Dadurch das wir an die Funktion in 2 der Variable den Wert 0 übergeben, werden diese nicht getriggert (ausgelöst) sondern nur zum späteren ausführen gespeichert.

Wenn wir nun in unserer Menu Klasse die Events triggern durch das Übergeben der Datensätze
PHP Code:
$this->data event('beforeMenuDisplay'$this->data); 
so sucht die Event Funktion nach Events des Namens beforeMenuDisplay und löst diese falls gefunden aus, in dem Fall währen das PluginMenuOrder und PluginMenuHide, die die Daten in der Theorie bearbeiten und anschließend werden die Daten wieder in die Menu Klasse eingeschweißt, ohne das die eigentliche Klasse zu extenden. Das hat dann wie gesagt den Vorteil das mehrere User/Module die Daten bearbeiten können, unabhängig davon was andere Plugins mit den Daten machen. Was für den Plugin Ersteller relevant ist sind ja nur die ID, der Link und dessen Name.

Rein theoretisch dürfte das auch mit Klassen und nicht nur mit Funktionen klappen, jedoch müsste man hier auf die Verwendung von call_user_func
verweisen, da diese dann Statische Klassen (Plugin Klasse) benötigt.

Meine Idee war es als erstes eine richtige Plugin Klasse zu schreiben die als Factory dient und die Plugins automatisch lädt und initialisiert. Und nachher auch nur ein Hook gesetzt wird an den die Plugins dann ausgeführt werden.

lg
paddelx3 is offline  
Old 07/13/2016, 21:08   #6

 
Mr.Tr33's Avatar
 
elite*gold: 2778
Join Date: Feb 2012
Posts: 3,527
Received Thanks: 1,044
Du baust ja jedes mal eine neue Instanz von Event auf, das doch falsch oder nicht? Wäre da eine statische Klasse nicht passender?

Bis jetzt habe ich es eigentlich verstanden, aber eins stört mich noch
Ich baue also in meinen Klassen überall Eventabfragen ein. Aber wo setze ich denn überall die Eventaktionen?
Mr.Tr33 is offline  
Old 07/13/2016, 22:31   #7
 
paddelx3's Avatar
 
elite*gold: 0
Join Date: Feb 2012
Posts: 202
Received Thanks: 133
Quote:
Originally Posted by Mr.Tr33 View Post
Du baust ja jedes mal eine neue Instanz von Event auf, das doch falsch oder nicht? Wäre da eine statische Klasse nicht passender?
Unsere Event Funktion ist ja keine Klasse somit haben wir auch im den Sinne keine richtige Instanz. static $events;. Dazu kannst du dir am besten mal die angucken. Man könnte nun auch hingehen und das ganze wie gesagt nach seinen belieben anpassen. Das ist ne Statische Klasse oder sonst was stecken. Das war auch mein erster Gedankengang als ich dein Thread gelesen hab, jedoch sind wir faule Leute und das währe nur unnötig mehr Arbeit.

Quote:
Originally Posted by Mr.Tr33 View Post
Bis jetzt habe ich es eigentlich verstanden, aber eins stört mich noch
Ich baue also in meinen Klassen überall Eventabfragen ein. Aber wo setze ich denn überall die Eventaktionen?
Das ist prinzipiell ganz einfach. Wie gesagt wir gehen davon aus, das unser Plugin immer eine Funktion hat, die die Daten bekommt. Diese eine Funktion nutzen wir als . Sprich diese wird aufgerufen und mit den Daten gefüttert, sobald ein Event triggert.

Nun weisen wir unser Plugin mit seiner Callback Funktion einen Event zu, das ganze passiert, sobald wir einen Callback mit angeben, der Wert der für den Callback genutzt wird aber immer noch NULL ist. Ein paar Beispiele wie wir unser Callback nun einen Event zuweisen: (oh seh gerade hab in meinen ersten Post paar schwere Fehler eingebaut :X, ist korrigiert)

PHP Code:
event('EventName'NULLbeispielCallbackFunctionOne($data) }); 
PHP Code:
event('EventName'NULLbeispielCallbackFunctionTwo($data) }); 
PHP Code:
event('EventName'NULLbeispielCallbackFunctionThree($data) }); 
Alles was wir jetzt noch machen müssen ist das Event zu triggern, indem wir die Daten übergeben. Das kann an einer beliebigen Stelle im Quellcode sein, da, wo wir's benötigen.

PHP Code:
$dataevent('EventName'$data); 
paddelx3 is offline  
Old 07/14/2016, 12:50   #8

 
Mr.Tr33's Avatar
 
elite*gold: 2778
Join Date: Feb 2012
Posts: 3,527
Received Thanks: 1,044
Das du eine neue Instanz aufbaust kam ich darauf, weil du ständig new event geschrieben hast
Und faul sein heißt nicht, dass es direkt gut und schön ist :P

Ebenfalls hast du irgendwie nur dich wiederholt
Ich habe jetzt einfach mal was schönes zusammen geworfen:
Code:
class Controller {
	private $menu;

	function __construct() {
		$this->menu = new Menu();
	}

	function draw(){
		$this->menu->display();
	}
}

class Menu {
	private $menuData = [];

	public function display() {
		$this->menuData = event("menuBeforeDisplay", $this->menuData);

		foreach ($this->menuData as $item)
			echo "<li>".$item."</li>";
	}
}

class MenuOrder {
	private $data;

	function __construct($menuData) {
		
	}

	public function getData() {
		return $this->data;
	}
}
In Menu habe ich nur die Abfrage vom Event.
Wo aber setze ich den Event bzw. baue MenuOrder ein? Einfach stumpf nachdem ich die Menu Instanz aufgebaut habe?
Mr.Tr33 is offline  
Reply


Similar Threads Similar Threads
[Buying] [Suche Methoden] Ich Suche Methoden um schnell an geld zu kommen [Biete E*Gold!]
04/10/2014 - elite*gold Trading - 4 Replies
Sage jetzt schonmal gleich vorab , ich suche nichts im Internet also keine Seiten wo man *Angeblich 100 Euro im Monat macht* . Ihr sollt mir auch keinen Job anbieten sondern sagen was man Mit 16 Jahren machen Könnte aber auch keine Sachen wie Autowaschen odersowas was man selber weiß! Meldet euch bei mir per PN.
OriginReallife.De NEU! DYNAMISCH!
09/08/2012 - Grand Theft Auto - 1 Replies
Kommt einfach anschauen unbeschreiblich geil! IP:176.9.46.83:5252
[C#] Schleifen, Methoden, Klassen und mehr!
03/10/2012 - Coding Tutorials - 8 Replies
#gelöscht



All times are GMT +1. The time now is 11:57.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.