Group: PHP-Entwicklung

Forums > Forum "PHP: Q & A" > Article thread "__construct bei statischem Aufruf"

Article thread - Articles 1-9 out of 9

  • __construct bei statischem Aufruf 07 Nov 2009, 4:53 pm

    Hallo,

    ich suche nach einer Möglichkeit, einen Konstruktor aufzurufen, auch wenn die Klasse statisch angesprochen wird.

    Beispiel:

    class Test {
    static $var;

    public function __construct() {
    self::$var = 'WERT';

    public function out() {
    return self::$var;
    }

    }

    }//class

    //Variante 1 (funktioniert)
    $inst = new Test();
    echo $inst->out(); //Gibt "WERT" aus


    //Variante 2 (funktioniert nicht)
    echo Test::out(); // Gibt "" aus.


    Es sollte aber in beiden Fällen "WERT" ausgegeben werden, egal wie ich die Klasse aufrufe.
    Gibt es also eine Möglichkeit, eine Art Konstruktor zu verwenden, oder eine Funktion, die bei jedem statischen Aufruf der Klasse vorab ausgeführt wird?

    Vielen Dank im vorraus & Grüße

    Boris Günther
  • Re: __construct bei statischem Aufruf 07 Nov 2009, 5:10 pm

    Boris Günther schrieb:
    >....
    //Variante 1 (funktioniert)
    $inst = new Test();
    echo $inst->out(); //Gibt "WERT" aus
     
     
    //Variante 2 (funktioniert nicht)
    echo Test::out(); // Gibt "" aus.
     
     
    Es sollte aber in beiden Fällen "WERT" ausgegeben werden, egal wie ich die Klasse aufrufe.

    Nein. out ist nicht statisch, braucht somit ein Objekt um in einem gültigen Kontext aufgerufen werden zu können.
    Zu mindest nach meinem Sprachverständnis.

    Gibt es also eine Möglichkeit, eine Art Konstruktor zu verwenden, oder eine Funktion, die bei jedem statischen Aufruf der Klasse vorab ausgeführt wird?Welchen Sinn sollte das ergeben?
    Eine statische Methode können sie so wohl aufrufen, aber jeder anderen fehlt der Kontext des Objektes.
    So könnte es höchstens gehen: new Test()->out();

    mfg.

    Jens Weller
  • Article only visible to registered members
  • Re^2: __construct bei statischem Aufruf 07 Nov 2009, 6:23 pm

    Hallo,

    statische "Konstruktoren" oder Codeblöcke wie Java kennt PHP nicht. Eigentlich ist das auch ganz gut so, weil der Code bzw. das Klassendesign durch deren Verwendung meist nicht wirklich besser wird.

    Erstmal sollten Sie das Klassendesign danach überprüfen, was die Variable nun ist. Ist sie abhängig von der Existenz einer Instanz dieser Klasse ist sie nicht statisch und die Methode out() muss es ebenfalls nicht sein.
    Soll die wirklich unabhängig von der/den Instanzen sein, fällt mir als einziger Grund für eine Art "statischen Konstruktur" ein, dass in PHP Klassen- und Instanzvariablen nur mit skalaren initalisiert werden können.

    Wollen Sie mit ihrem Vorgehen also Test::$var mit einem Object oder so initialiseren, würde ich folgendes Vorgehen vorschlagen:

    class Test {
    // gibt es "private für statische Variablen überhaupt?, egal auf jeden Fall sollte nicht direkt
    // auf die Variable zugegriffen werden
    private static $var = null;


    public function VAR() {
    if (is_null(self::$var)) {
    // initalisiere die Variable;
    }

    return self::$var;
    }


    public function out() {
    return self::VAR();
    }
    }


    Alternativ geht auch dieses (ist von der Kapselung schöner, allerdings kann die Variable außerhalb von VAR() nicht verändert werden):

    class Test {
    private function VAR() {
    static $var = null;
    if (is_null($var)) {
    // initalisiere die Variable;
    }

    return $var;
    }


    public function out() {
    return self::VAR();
    }
    }


    Viele Grüße

    Karsten Kraus
    This article was modified on 07 Nov 2009 at 06:27 pm.
  • Article only visible to registered members
  • Re^2: __construct bei statischem Aufruf 07 Nov 2009, 11:00 pm

    Hallo zusammen,

    vielen Dank für die schnellen Antworten. Mittlerweile konnte ich das Problem umschiffen indem ich eine Masterklasse habe, welche bei der Anmeldung am System via Kindklasse die statischen Variablen befüllt und somit für alle von der Masterklasse abgeleiteten Klassen bereitstellt.

    Um etwas Hintergrund zum Problem zu geben - es handelt sich um eine Art globalen Cache für Spalten und Eigenschaften, den ich teilweise in einer Instanz benötige, teilweise aber lieber statisch ansprechen möchte um nicht jedesmal die Klasse zu instanzieren. Das Ganze wird in ZF entwickelt, wo man es recht schön mit den Klassen realisieren kann.

    MfG

    Boris Günther
  • Re^3: __construct bei statischem Aufruf 08 Nov 2009, 3:05 pm

    Hallo Herr Günther,

    schon der Titel dieses Threads sollte bei einem erfahrenen Programmierer sämtliche Alarmglocken läuten lassen. Zum einen in Bezug auf die (spätere) Nachvollziehbarkeit des Codes, zum anderen im Hinblick auf seine Testbarkeit.

    Sowohl die hier vorgeschlagenen Singletons als auch der Gebrauch von statischen Variablen und Methoden führen in der Regel zur Entstehung eines "Global State", d.h. zu einem globalen Zustand innerhalb Ihrer Applikation, der unnötige Abhängikeiten erzeugt und es erschwert bzw. unmöglich macht, einzelne Units in Isolation auszuführen bzw. zu testen.

    Misko Hevery von Google äußert sich dazu ausführlich in seinem Blog, z.B. ausgehend von http://misko.hevery.com/2008/12/15/static-methods-are-death-... .

    Vor diesem Hintergrund macht es möglicherweise Sinn, Ihr Design nochmals genauer überdenken.

    Schöne Grüße aus Karlsuhe,

    S. Schomberg
    This article was modified on 08 Nov 2009 at 03:27 pm.
  • Re^3: __construct bei statischem Aufruf 08 Nov 2009, 5:33 pm

    Hallo,

    Um etwas Hintergrund zum Problem zu geben - es handelt sich um eine Art globalen Cache für Spalten und Eigenschaften, den ich teilweise in einer Instanz benötige, teilweise aber lieber statisch ansprechen möchte um nicht jedesmal die Klasse zu instanzieren. Das Ganze wird in ZF entwickelt, wo man es recht schön mit den Klassen realisieren kann.
    Hmmm... ehrlich gesagt, für mich klingt das nicht schlüssig. Was spricht den gegen die Instantierung? Der Overhead im Konstruktor? Dann sollte man den Cache entweder als Singleton realisieren (wobei dagegen in der Tat spricht, das Global-State fürs testen immer schlecht und auch sonst nicht elegant ist), oder diesen möglichst früh instantieren und dann jeweils an die anderen Objekt-Instanzen die darauf zugreifen müssen übergeben (z.B. in deren Konstruktor).

    Im Zend-Framework ließe sich ihr Problem vermutlich sogar richtig elegant über Dependency-Injection lösen: http://www.ibuildings.co.uk/blog/archives/1181-Dependency-In...


    Viele Grüße

    Karsten Kraus
    This article was modified on 08 Nov 2009 at 05:37 pm.
  • Re^4: __construct bei statischem Aufruf 08 Nov 2009, 6:09 pm

    Karsten Kraus schrieb:
    Im Zend-Framework ließe sich ihr Problem vermutlich sogar richtig elegant über Dependency-Injection lösen:
    Dependency Injection ist immer elegant und durchaus ein Thema was man sich einmal genauer ansehen sollte, unabhängig vom verwendeten Framework. Aber in Verbindung mit dem Zend Framework von einer eleganten Lösung zu sprechen scheint mir etwas widersprüchlich.

    Grüße aus Mannheim,
    Stephan Hochdörfer

Forums > Forum "PHP: Q & A" > Article thread "__construct bei statischem Aufruf"

Top