johny7: Objekte referenzieren

Moin allerseits,

ich arbeite gerne mit Objekten. Das Problem ist nur, wie greife ich korrekt auf sie zu? Z.B. habe ich das Array von getdate() in ein Objekt umgewandelt. In getdate() gibt es einen Wert mit dem Key '0'. Wie greife ich drauf jetzt als Objekt zu?

  
$my = (object) getdate();  
echo $my->0;  

Der obige Code produziert einen Fehler.

Weiter habe ich eine Frage zum Zugriff auf variable Eigenschaften. Ich habe im PHP-Handbuch gelesen, habe aber keine Antwort auf meine spezielle Frage gefunden.

Wenn ich z.B. in meiner Klasse verschiedene Eigenschaften habe, kann ich so darauf zugreifen:

  
$eigenschaft = 'dicke'; // oder 'breite' etc.  
$this->$eigenschaft = 10;  

Kann ich denn eine Kombination zwischen Variable und absolutem Text ohne Zwischenspeicherung verwenden, um die Eigenschaft zu referenzieren?

  
$this->('Frankfuhrt'.$fluss);  

Und wie verwende ich den Inhalt einer Eigenschaft als Eigenschaftsnamen? Ich musste bisher Zwischenspeichern.

  
$temp = $this->Namenssatz;  
echo $this->$temp;  
// Folgendes funktioniert nicht:  
$this->($this->Namenssatz);  

Grüße, JN

--
ie:{ fl:( br:^ va:| ls:[ fo:| rl:? n4:? ss:| de:] js:| ch:? sh:( mo:| zu:)
http://www.johny7.de
  1. Hi!

    Vorab: Das hört sich alles ziemlich wenig sinnvoll an, was du da vorhast. Wenn du für irgendetwas keine technische Begründung parat hast, dann lass es lieber. Das erzeugt sonst nur Aufwand und Irritationen beim Codeleser, geschweige denn von Nebenwirkungen, die du nicht vorhersiehst.

    Weiter habe ich eine Frage zum Zugriff auf variable Eigenschaften.

    Das geht so ähnlich wie bei den variablen Variablen: mit {}-Klammern - und zwar für alle deine Fragen.

    Generell sollte man variable Variablen (auch bei OOP) nur mit Bedacht einsetzen. Da du immer erst zur Laufzeit weißt, was tatsächlich passiert, fördert das zum einen nicht die Übersichtlichkeit des Codes und zieht zum anderen zusätzliche Prüfungen beispielsweise auf Existenz nach sich, die sonst bei gewöhnlichen fest benannten Variablen überflüssig sind.

    Lo!

  2. Hi.

    Als Ergaenzung zu dedlfix' genereller Empfehlung:

    Z.B. habe ich das Array von getdate() in ein Objekt umgewandelt. In getdate() gibt es einen Wert mit dem Key '0'. Wie greife ich drauf jetzt als Objekt zu?

    Da kriegst Du ein Problem, siehe im Handbuch das Beispiel, das mit 'CAUTION:' ueberschrieben ist.

    Einfach aus kosmetischen Gruenden ein Array in ein Objekt zu verwandeln, bringt zunaechst mal keinen Vorteil, aber Nachteile mit sich. Ist also nicht empfehlenswert, auch wenn der eigene Sinn fuer Aesthetik darunter leidet.

    Viele Gruesse,
    der Bademeister

  3. Moin!

    ich arbeite gerne mit Objekten.

    Etwas verwunderlich, weil dein Code und deine Absichten hier mir nicht wirklich zeigen, dass du mit objektorientierter Programmierung schon Erfahrung hast.

    Das Problem ist nur, wie greife ich korrekt auf sie zu?

    Das Problem ist auch, dass du Dinge mit den Objekten tust, die man normalerweise so eher vermeiden würde.

    Z.B. habe ich das Array von getdate() in ein Objekt umgewandelt. In getdate() gibt es einen Wert mit dem Key '0'. Wie greife ich drauf jetzt als Objekt zu?

    $my = (object) getdate();
    echo $my->0;

    
    > Der obige Code produziert einen Fehler.  
      
    Der obige Code ist extrem unpraktisch. Du erzeugst ein Objekt der Klasse "stdObject", welche keinerlei Methoden kennt und nur ein Objektcontainer für deine Array-Eigenschaften ist. Keine Entwicklungsumgebung dieser Welt wird dir Code-Completion dafür anbieten, d.h. du musst die Aufrufe deiner Objekteigenschaften ohne Tippfehler hinkriegen. Bei Lesezugriff auf nichtexistente Eigenschaften kriegst du immerhin noch eine Notice, Schreibzugriff wird nicht bemängelt.  
      
    Obendrein existiert keinerlei Kontrolle über die Zulässigkeit der Werte, die diese Klasse in ihren Eigenschaften speichern soll.  
      
    Summa summarum: So wie die beabsichtigte Nutzung der Klasse zu ahnen ist, ist das Objekt einfach nur ein besseres Array ohne jeglichen Vorteil, stattdessen jetzt ein Objekt zu sein.  
      
    Was "man" stattdessen bei objektorientierter Programmierung tun würde:  
    - Eine Klasse schreiben, die getdate() im Konstruktor aufruft und in objektinternen Speicher schreibt.  
    - Methoden zum Abrufen aller gewünschten Informationen schreiben (sogenannte "getter").  
      
    - ODER: Direkt die existierende Klasse [DateTime](http://de2.php.net/manual/en/class.datetime.php) verwenden - die ist schließlich genau für diesen Zweck da, und ab PHP 5.3 hinsichtlich der verfügbaren Datums-Rechenfunktionen auch wirklich nützlich.  
    - Und wenn DateTime nicht alle gewünschten Funktionen bietet, dann erweitert man diese Klasse durch eigenen Code, der die fehlende Funktionaltät hinzufügt.  
      
    In jedem Fall erhält man eine Klasse, die man in anderen Methoden und Funktionen per Type-Hinting auch fordern kann, dadurch in Entwicklungsumgebungen deutlich bessere Unterstützung beim Code-Check, Auto-Complete etc., und der gesamte Code wird deutlich transparenter, verständlicher und lesbarer.  
      
    Also:  
    ~~~php
      
    $jetzt = new DateTime();  
    echo $jetzt->getTimestamp();  
    
    

    Weiter habe ich eine Frage zum Zugriff auf variable Eigenschaften. Ich habe im PHP-Handbuch gelesen, habe aber keine Antwort auf meine spezielle Frage gefunden.

    Variable Eigenschaften sind wie variable Variablen Teufelszeug. Sie erzeugen unleserlichen, unverständlichen Code, und sie lassen sich immer durch entsprechende Programmierung in Gettern und Settern explizit formulieren - und das insbesonder nur genau EINMAL in eben diesem Getter, nicht ständig überall, wo der Zugriff auf diese variable Eigenschaft geschehen soll.

    Wenn ich z.B. in meiner Klasse verschiedene Eigenschaften habe, kann ich so darauf zugreifen:

    $eigenschaft = 'dicke'; // oder 'breite' etc.
    $this->$eigenschaft = 10;

      
    Sowas will man nicht. Wenn dir irgendwo ein Tippfehler unterläuft, oder du die Variable $eigenschaft unbeabsichtigt veränderst, greift dein Code nicht mehr auf die Objekteigenschaft "dicke" zu, sondern auf etwas anderes.  
      
    Diese Herangehensweise enthält keinerlei Methodik, um zu validieren, ob die gewünschte Eigenschaft existiert. Nirgendwo ist in der Klasse dokumentiert, welche Eigenschaften es eigentlich tatsächlich gibt. Sowas ist extrem schwer zu debuggen.  
      
    Mit Gettern hat man zumindest noch eine Chance, und der Code wird auch direkt klarer:  
      
    ~~~php
      
    $this->setWidth(10);  
    $this->setHeight(20);  
    
    

    Wenn es unbedingt variabel sein muss:

      
    $this->setProperty('dicke', 10);  
    $this->setProperty('hoehe', 20);  
    
    

    Den String kann man sich dann dynamisch zusammensetzen, und die Methode setProperty() hat eine Chance, das Resultat des übergebenen Strings auf Gültigkeit zu prüfen und im Fehlerfall eine Exception zu werfen.

      
    public function someCode() {  
        // ...  
        $this->setProperty('dicke', 10);  
        // ...  
    }  
      
    // ...  
      
    // Initiale Belegung der Eigenschaften - was hier  
    // nicht drinsteht, kann nicht gesetzt werden!  
    protected $_date = array('dicke' => 0, 'hoehe' => 0);  
      
    public function setProperty($name, $value) {  
        if (isset($this->_data[$name])) {  
            $this->_data[$name] = $value;  
            return;  
        }  
        throw new InvalidArgumentException('The property "'.$name.'" cannot be set.');  
    }  
    
    

    Zu den in der SPL vordefinierten nützlichen Exceptions siehe http://de2.php.net/manual/en/spl.exceptions.php. Im Zweifel tut es die stinknormale Standard-Exception "Exception" von PHP.

    Kann ich denn eine Kombination zwischen Variable und absolutem Text ohne Zwischenspeicherung verwenden, um die Eigenschaft zu referenzieren?

    $this->('Frankfuhrt'.$fluss);

      
    Mit Gettern ja, recht problemlos.  
      
    
    > Und wie verwende ich den Inhalt einer Eigenschaft als Eigenschaftsnamen? Ich musste bisher Zwischenspeichern.  
    > ~~~php
      
    
    > $temp = $this->Namenssatz;  
    > echo $this->$temp;  
    > // Folgendes funktioniert nicht:  
    > $this->($this->Namenssatz);  
    > 
    
    

    Diese doppelte Indirektheit schießt dir innerhalb kürzester Zeit in dein eigenes Knie, weil du unglaublich undurchsichtigen Code produzierst.

    - Sven Rautenberg