php.de

Zurück   php.de > Webentwicklung > PHP Einsteiger

PHP Einsteiger PHP Problemlösungen für Spracheinsteiger
Archive: 2004, 2004/2, 2005, 2005/2, 2006, 2007, 2008, 2009, 2010,

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 24.01.2012, 00:59  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.631
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard [Erledigt] Workaround für fehlende Mehrfachvererbung

Servus

da PHP 5.4 noch nicht spruchreif ist und ich somit nicht auf Traits zurückgreifen kann suche ich nach einer anderen Lösung für die fehlende Mehrfachvererbung in PHP.

Konkret geht es darum das ich in meinem Framework eine Basisklasse habe welche Funktionen zur Verfügung stellt die fast jede Klasse braucht damit mein Konzept aufgeht.

Nun bin ich an einem Punkt angekommen wo ich gerne eine Klasse von SimpleXMLElement ableiten möchte, da ich dieser Klasse weitere Methoden und Attribute hinzufügen möchte.

Ohne Mehrfachvererbung kann ich nicht von beiden Klassen auf gleicher Ebene erben, und ich kann SimpleXMLElement auch nicht von meiner Basisklasse erben lassen.

Genauso wenig möchte ich die Methoden aus meiner Basisklasse doppelt implementieren müssen, da diese ansonsten ihren Sinn verliert.

Per Google finde ich unter den Suchbegriffen "php mehrfachvererbung workaround" o. Ä. leider nichts gescheites was diesen Anforderungen gerecht wird.

Mir kam jetzt folgende Idee:

Ich teile die Logik meiner Klasse auf, in etwa so:

PHP-Code:
class BaseClass {

   protected function 
doSomethingBasic() {
      return 
$something;
   }

}

class 
XMLElementBase extends BaseClass {

   public function 
doBaseClassOperation() {
      return 
$this->doSomethingBasic();
   }

}

class 
ExtendedXMLElement extends SimpleXMLElement {

   private 
$baseObject null;

   public function 
__construct() {
      
$this->baseObject = new XMLElementBase();
   }

   public function 
doXMLZeug() {
      
$this->baseObject->doBaseClassOperation();
      
      
//und hier die eigentliche methodenimplementierung
   
}

Die Implentierung, welche ich eigentlich in eine Methode stecken würde, teile ich auf diese und die Methode einer zweiten Klasse auf welche Zugriff auf die Methoden der Basisklasse hat.

Nun finde ich es sehr unschön die Logik so zu "splitten".

Fällt euch eine bessere Lösung ein welche die oben genannten Anforderungen erfüllt und mich nicht dazu zwingt die Methoden der Basisklasse "public" zu machen?
__________________
"Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".
Dark Guardian ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 24.01.2012, 07:25  
fab
Erfahrener Benutzer
 
Benutzerbild von fab
 
Registriert seit: 28.07.2010
Beiträge: 2.308
PHP-Kenntnisse:
Fortgeschritten
fab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblick
Standard

Der Ausdruck "Splitten" impliziert eigentlich dass du etwas teilst, was ursprünglich zusammengehört. Ich würde sagen, das Gegenteil ist der Fall. Mit Methodennamen wie doSomethingBasic lässt sich schwer argumentieren aber alleine dass dein Lösungsvorschlag offenbar funktioniert obwohl die Methode von BaseClass keinen Zugriff auf die Interna des konkreten Objeks hat, deutet darauf hin, dass du die Vererbung nur zum Bereitstellen von Funktionen missbrauchst.
fab ist offline   Mit Zitat antworten
Alt 24.01.2012, 08:52  
Erfahrener Benutzer
 
Registriert seit: 26.11.2008
Beiträge: 264
dsentker befindet sich auf einem aufstrebenden Ast
Standard

Was genau kann denn deine "BaseClass"? Auch ich war mal auf dem Trip, jede Klasse meines Frameworks von einer Basisklasse abzuleiten, die grundlegende Methoden zur Verfügung stellt. Als ich meinen DI-Container entwickelte, wurde dieses "Problem" aber obsolet. Mehrfachvererbung ist zu Recht nicht Teil von PHP, da es ungeahnte Konsequenzen mit sich bringt. Denk nur z.B. an die Methode "getNamespaces", die in der BaseClass hättest und ebenfalls Teil von SimpleXML ist.

Warum nicht, wenn es schon eine BaseClass sein muss, so etwas?
PHP-Code:
abstract class BaseClass() {
   public function 
doSomething() { 
      ...
   }
}

class 
SomeConcreteClass extends BaseClass {
   
   protected 
$xmlProcessor;

   public function 
__construct(SimpleXML $xmlProcessor) {
       
$this->xmlProcessor $xmlProcessor;
   }


__________________
dsentker ist offline   Mit Zitat antworten
Alt 24.01.2012, 09:44  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.631
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard

@fab
Die Basisklasse braucht keinen Zugriff auf die Member der Kindklasse. Die Kindklasse aber auf die Member der Basisklasse. Durch den Rückgabewert der Methoden kann ich somit das Resultat der Logik welche auf Methoden/Member der Basisklasse basiert an meine eigentliche Implementierung weiterreichen. Außerdem könnte ich über Parameter benötige Informationen aus dem SimpleXMLElement weiterreichen, falls nötig. Ich hätte also beidseitig Zugriff wenn es nötig wäre.

@dsentker
Ich müsste hier jetzt "sehr" weit ausholen denn wenn ich gewisse Schlagwörter in den Raum werfen würde kämen als erstes Fragen warum ich das nicht anders realisiere womit ich hier mein komplettes Konzept ausbreiten müsste was nicht wenige DIN A4 Seiten umfasst.

Um es halbwegs knapp zu formulieren: Es geht um ein komplexes System welches ohne globale Zugriffspunkte (Singleton, globale Variablen, o.Ä.) auskommen soll und dennoch die Möglichkeit bietet auf den konkreten Scriptablauf zur Laufzeit Einfluss zu nehmen. Dazu benötige ich die Methoden der Basisklasse welche dies gewährleisten soll, oder in meinem hier definiertem Beispiel zumindest die Möglichkeit auf die Rückgabe dieser Methoden/Member, welche die Ausführung "steuern" können, Zugriff zu erhalten.

Mehrfachvererbung macht in PHP nur Probleme aufgrund der fehlenden Typsicherheit. Ansonsten wären die Methoden anhand ihrer Signatur auch bei gleichem Namen durchaus zu unterscheiden.

Dein Beispiel hatte ich zunächst auch so implementiert. Jedoch muss ich dafür zunächst über den SimpleXML Baum laufen und einen Getter für das Objekt implementieren um das gleiche zu erreichen.

Nun wäre es warscheinlich so das dieser Weg jedoch der performantere wäre... dann müsste ich halt wieder auf einen Getter zurückgreifen.

Das meine "Idee" alles andere als gut ist war mir bewusst, aber da es wohl keine praktikable Alternative zu letzterem gibt werde ich wohl wieder darauf zurückgreifen.
__________________
"Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".

Geändert von Dark Guardian (24.01.2012 um 09:52 Uhr).
Dark Guardian ist offline   Mit Zitat antworten
Alt 24.01.2012, 09:56  
Erfahrener Benutzer
 
Registriert seit: 13.05.2009
Beiträge: 1.166
PHP-Kenntnisse:
Fortgeschritten
dennis81 befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von Dark Guardian Beitrag anzeigen
Mehrfachvererbung macht in PHP nur Probleme aufgrund der fehlenden Typsicherheit.
Mehrfachvererbung macht nicht nur in PHP Probleme. Es gibt auch mehr als nur Methoden.
__________________
Es ist schon alles gesagt! Nur noch nicht von allen! (Karl Valentin)
Wenn du eine weise Antwort verlangst, musst du vernünftig fragen. (Johann Wolfgang von Goethe)
dennis81 ist gerade online   Mit Zitat antworten
Alt 24.01.2012, 10:02  
Erfahrener Benutzer
 
Registriert seit: 26.11.2008
Beiträge: 264
dsentker befindet sich auf einem aufstrebenden Ast
Standard

Da ich dein Projekt oder deine Idee nicht kenne, darf ich sie eigentl. nicht kritisieren. Es scheint mir aber, als ob du Probleme versuchst zu umgehen, du dadurch aber neue schaffst.
Zitat:
Zitat von Dark Guardian
Dein Beispiel hatte ich zunächst auch so implementiert. Jedoch muss ich dafür zunächst über den SimpleXML Baum laufen und einen Getter für das Objekt implementieren um das gleiche zu erreichen.
Naja, das ist aber nichts ungewöhnliches. Und ein Getter ist nicht zwingend notwendig, wenn du auf das Property direkt zugreifst.

Zitat:
Nun wäre es warscheinlich so das dieser Weg jedoch der performantere wäre
Ich denke, da tut sich nicht viel...
__________________
dsentker ist offline   Mit Zitat antworten
Alt 24.01.2012, 10:10  
Erfahrener Benutzer
 
Registriert seit: 01.09.2010
Beiträge: 4.561
PHP-Kenntnisse:
Fortgeschritten
eagle275 ist ein sehr geschätzer Menscheagle275 ist ein sehr geschätzer Menscheagle275 ist ein sehr geschätzer Mensch
Standard

also ohne die vorherigen Antworten alle vollständig gelesen zu haben, verweise ich hier mal auf den Weg, den man in Java geht - dort gibt es ja auch erzwungene Einfach-Vererbung ... Mehrfach-Vererbung löst man in Java durch Interfaces, davon darf eine Klasse - neben ihrer Elternklasse - sogar mehrere haben, die dann natürlich besondere Aufmerksamkeit beim Ausprogrammieren erfordern (gleiche Methodennamen sind tödlich)
__________________
"Irren ist männlich", sprach der Igel und stieg von der Drahtbürste
eagle275 ist offline   Mit Zitat antworten
Alt 24.01.2012, 10:24  
Erfahrener Benutzer
 
Registriert seit: 22.01.2005
Beiträge: 606
Connar befindet sich auf einem aufstrebenden Ast
Standard

@eagle275: Ich glaube das hilft ihm jetzt nicht wirklich weiter, da er nicht danach sucht Methoden nach außen hin zu veröffentlich sondern intern nutzen zu können. Also benötigt er weniger das Interface als viel mehr die spezielle Implementierung.

Also ich finde die bereits beschrieben Ansätze sehr sinnvoll (entweder die Basisklasse als Member-Variable oder eben z.B. den XML Processor). Ich hab mich allerdings gefragt, wie du es durch Vererbung erreichen willst, dass du keinerlei globale Variable (inklusive Singletons, etc.) mehr hast. Irgendwo wirst du doch vermutlich auch in der Vererbung auf feste Daten zugreifen wollen, die immer gleich sind, oder werden in den Funktionen (der Basisklasse) nur Operationen ausgeführt, die von keinen Attributen (der Basisklasse) abhängen?


MFG Connar
Connar ist offline   Mit Zitat antworten
Alt 24.01.2012, 10:38  
fab
Erfahrener Benutzer
 
Benutzerbild von fab
 
Registriert seit: 28.07.2010
Beiträge: 2.308
PHP-Kenntnisse:
Fortgeschritten
fab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblick
Standard

Zitat:
Zitat von Dark Guardian Beitrag anzeigen
@fab
Die Basisklasse braucht keinen Zugriff auf die Member der Kindklasse. Die Kindklasse aber auf die Member der Basisklasse. Durch den Rückgabewert der Methoden kann ich somit das Resultat der Logik welche auf Methoden/Member der Basisklasse basiert an meine eigentliche Implementierung weiterreichen. Außerdem könnte ich über Parameter benötige Informationen aus dem SimpleXMLElement weiterreichen, falls nötig. Ich hätte also beidseitig Zugriff wenn es nötig wäre.
Ach ja, deshalb die Proxy-Klasse, die die Basisklasse "aufbricht". Dass das nicht schön ist, sagst du selbst schon.

Es soll also jedes Objekt bestimmte zusätzliche Eigenschaften haben. Selbst bei einer flexiblen Sprache wie JavaScript, wo das durch eine Erweiterung des passenden Prototypen einfach möglich ist, wird dazu geraten, damit sehr sparsam umzugehen bzw. es möglichst zu vermeiden.

Auch wenn du dein Konzept hier nicht ausbreiten und diskutieren willst, werfe ich mal alternative Ansätze in den Raum - ob für deinen Fall anwendbar, musst du selbst entscheiden:

- Meta-Daten zu Objekten könnten in einer speziellen Registry mit SplObjectStorage (map from objects to data) untergebracht werden
- Methoden, die darauf operieren leben in einer eigenen Klasse und bekommen das konkrete Objekt als Parameter

Einfache Lösung, widerspricht aber der Anforderung "ohne globale Zugriffspunkte". Zweite Idee:

- Behalte den Kompositions-Ansatz bei, aber nicht als Workaround für Mehrfachvererbung sondern um Vererbung komplett herauszulassen (die mmN von vorneherein fehl am Platz war). Das einzige, was all deine Klassen dann gemeinsam haben sollten ist:
PHP-Code:
protected $_meta;
public function 
__construct()
{
  
$this->_meta = new MetaObject($this);

Das sind zwei Zeilen zusätzlicher Boilerplate-Code, dafür braucht es keine Vererbung, nichtmal Traits würden sich lohnen. Ach ja, die "Basismethoden" sollen exponiert werden. Also, führen wir ein Interface für alle deine Klassen ein:

PHP-Code:
interface HasMetaObject
{
  
/**
   * @return MetaObject
   */
  
public function getMetaObject();

- MetaObject enthält nun alle Methoden, die bei dir in BaseClass waren, allerdings sämtliche öffentlich. Willst du einzelne Methoden so beschränken, dass sie nur vom zugehörigen Objekt selbst aufgerufen werden können, geht das in PHP nur zur Laufzeit, das würde ich allerdings als Schönheitsfehler hinnehmen und nur in der Dokumentation festhalten.

Du siehst, diese Lösung ist deiner ziemlich ähnlich, kommt aber quasi von der anderen Seite. Wir nehmen keine Basis-Klasse und brechen sie auf, sondern ein zusätzliches Objekt und hängen es an.
fab ist offline   Mit Zitat antworten
Alt 24.01.2012, 10:38  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.631
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard

Zitat:
Zitat von dsentker Beitrag anzeigen
Da ich dein Projekt oder deine Idee nicht kenne, darf ich sie eigentl. nicht kritisieren. Es scheint mir aber, als ob du Probleme versuchst zu umgehen, du dadurch aber neue schaffst.
Die fehlende Mehrfachvererbung ist das erste Problem in das ich renne, und bisher habe ich sehr selten Vererbung eingesetzt weswegen ich nicht davon ausging jemals von 2 Klassen erben zu müssen. I.d.R. reichen mir auch Interfaces. Nur in diesem speziellem Fall leider nicht.

Das "Problem" ist ja auch hausgemacht. Ich wollte mir das Durchlaufen des XML Baumes sparen um die Klasse SimpleXMLElement erweitern zu können, da dies aber ohne Mehrfachvererbung nicht ohne gleichem oder höherem Aufwand zu lösen zu sein scheint, greife ich auf diesen Weg zurück.

Zitat:
Zitat von dsentker Beitrag anzeigen
Naja, das ist aber nichts ungewöhnliches. Und ein Getter ist nicht zwingend notwendig, wenn du auf das Property direkt zugreifst.
Da die Eigenschaft read-only sein soll habe ich keine andere Wahl. Ansonsten könnte der Wert auch auf "null" o.A. gesetzt werden was Probleme bereitet.

Zitat:
Du siehst, diese Lösung ist deiner ziemlich ähnlich, kommt aber quasi von der anderen Seite. Wir nehmen keine Basis-Klasse und brechen sie auf, sondern ein zusätzliches Objekt und hängen es an.
Ich bin eigentlich auch kein Freund von Vererbung sehr abstrakter Eigenschaften/Methoden wie ich es tue. Dein zweiter Absatz wäre auch durchaus machbar und definitiv "sauberer", da durch das Interface definiert werde welche Klasse diese Eigenschaft besitzt und welche nicht. Das einzige was dem ggf. einen Stein in den Weg lege würde wäre die Performance da ich konsequent 2 Objekte instanzieren müsste. Ich setze es zumindest mal mit auf die Agenda.
__________________
"Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".

Geändert von Dark Guardian (24.01.2012 um 10:50 Uhr).
Dark Guardian ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Fehlende Klasse (SOAP) bei Freehoster Atikos PHP Einsteiger 2 26.02.2011 10:18
[Erledigt] Workaround für fehlendes PDO::MYSQL_ATTR_FOUND_ROWS bzw. Bug in DBO::rowCo Dawn Datenbanken 9 31.01.2011 11:38
[Erledigt] Konstruktoraufruf bei Mehrfachvererbung hts JavaScript, Ajax und mehr 5 09.01.2011 17:28
Fehlende Werte im Index füllen akogler Datenbanken 6 29.12.2010 20:49
MySQL, fehlende Datensätze!? The Virusman PHP Einsteiger 5 14.12.2010 14:44
[Erledigt] Fehlende Umlaute im HTML phreund PHP-Fortgeschrittene 4 10.12.2010 14:28
[Erledigt] Fehlende Rechte auf /tmp -> Probleme mit Sessions Gemouen PHP Tipps 2009 3 28.10.2009 21:59
Padding IE Table workaround oder css-hack? Circushund HTML, Usability und Barrierefreiheit 10 16.05.2009 19:17
Abfrage auf fehlende ID in einer Tabelle maeck Datenbanken 2 04.07.2007 19:44
imagefillrectangle mit transparenz workaround? Promaetheus PHP Tipps 2006 2 20.10.2006 04:46
Fehlende Einträge in Tabelle finden Cyberbob_at_tot Datenbanken 17 29.06.2006 15:39
fehlende MYSQL-extension für PHPMyaAdmin FatherDeath Datenbanken 3 20.05.2006 15:56
Fehlende MySQL-Clients? Datenbanken 1 29.07.2005 12:46
Fehlende Zahlen suchen und Reihung ändern.... MortakArtos PHP-Fortgeschrittene 5 26.09.2004 12:21
[Erledigt] fehlende Zeilenumbrüche in Text E-mail (php / mysql) Datenbanken 6 30.08.2004 13:11

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php mehrfachvererbung, fehlende mehrfachvererbung, java mehrfachvererbung workaround, php mehrfach vererbung, welcher freehoster hat php 5.4

Alle Zeitangaben in WEZ +2. Es ist jetzt 21:36 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum