statische klassen in php 4.x

Josh

Legendäres Mitglied
hi alle.

für eine app benötige ich statische klassen. klar, man kann einfach

ClassName::functionName($xy)

aufrufen, sodass man keine instanz erzeugen muss, aber leider kann man so der klasse auch keine dauerhaften variablen assignen:

ClassName::attributeName = "xxx";

bricht mit einem Fehler ab, und

ClassName::setAttributeName("xxx");

funktioniert zwar zum schein, aber die variable geht einfach im nichts verloren.
rolleyes.gif


ich habe nun eine lösung gefunden, indem ich die globale variable $GLOBALS verwende. klar wird jetzt jeder schreien, man soll keine globalen variablen verwenden, aber ich denke mal, ich habe doch ein recht affensicheres system erfunden.
wink.gif


wenn jemand daran interessiert ist, dann kann ich die klasse veröffentlichen; es ist eine klasse, welche abgeleitet werden sollte. also kann man sie mit allen möglichen funktionen ergänzen, aber sie bleibt statisch (kann nicht per new erzeugt werden).

hat sonst mal jm hier erfahrungen mit statischen klassen in php gemacht? ich weiss, dass php5 da meilen weitergekommen ist, aber solange ich scripts übers internet verbreite und php5 noch lange nicht auf jedem server vorhanden ist, muss ich wohl oder übel auf meine lösung zurückgreifen.
wink.gif


gruss
j0sh
 
Ich bin mir jetzt wirklich gar nicht mehr sicher, ob ich überhaupt verstanden habe, wass du da schreibst.
Wieso willst du die Klasse nicht instanzieren?

"Statische" Variablen hab ich immer so gemacht, eine einzige Instanz:

CODE $foo = new foo("this is bar");

class foo {

var $bar;

function foo($input = "standard bar") {
$this->bar = $input;
}

function print_foo($el = "<br>") {
echo $this->bar.$el;
}

function set_foo($input) {
$this->bar = $input;
}

}

$foo->print_foo();

$foo->set_foo("another bar");

$foo->print_foo();

$foo->bar = "asdf";

echo $foo->bar;

->this is bar<br>another bar<br>asdf
 
das ist schön und recht, solange du nur im rahmen des php-dokuments selber auf die klasse zugreifen willst. aber nehmen wir an, wir wollen einen logger haben, welcher von jeder klasse benutzt werden kann und praktische log-einträge in eine log.txt schreibt:

CODE class Something {

$logger = new LOGGER();
$logger->setOutputTarget("log.txt"); // schreibe logs in log.txt
$logger->setLoggingLevel("USER"); // schreibe nur logs, welche den status "USER" oder drunter haben
function doSomething() {
$logger->logDebug("entering doSomething()"); // wird nicht geloggt, da status "DEBUG" grösser ist als "USER"

$this->doSomeUserAction();
$logger->logUser("Der User tut irgendwas wichtiges"); // wird geloggt

$logger->logDebug("leaving doSomething"); // wird nicht geloggt, da status "DEBUG" grösser ist als "USER"
}
}

so weit, so gut.
smile.gif


doch was machen wir nun, wenn wir mehr Klassen als nur die klasse Something haben und von jeder klasse aus den logger verwenden wollen? dazu müssten wir das ganze initialisieren des loggers wiederholen:


CODE class SomethingElse {

$logger = new LOGGER();
$logger->setOutputTarget("log.txt"); // schreibe logs in log.txt
$logger->setLoggingLevel("USER"); // schreibe nur logs, welche den status "USER" oder drunter haben

// some functions()...
}

das funktioniert an sich, aber was, wenn wir den logging-level von "USER" auf "DEBUG" ändern wollen, weil wir genauere logs haben wollen? dann müssten wir in jeder einzelnen klasse von hand setLoggingLevel("XXX") ändern, was aber umständlich ist wenn man tonnenweise klassen hat, welche alle auf den logger zugreifen.

alternativ könnte man es irgendwie machen, dass man statisch auf den logger zugreift, indem man statt "$this->logUser()" immer "LOGGER::logUser()" verwendet. so würde jede klasse immer genau auf dieselbe (an sich nicht vorhandene instanz) zugreifen, aber man müsste den loggingLevel dann immer innerhalb der klasse LOGGER selber anpassen, da man eben keine variablen dieser inexistenten instanz hinzufügen kann (per LOGGER::myVar = "xyz" => gibt error!). schon etwas einfacher, aber noch lange nicht wirklich schön dynamisch.

und HIER setzt meine theorie ein. auch bei meinem LOGGER werden alle klassen mit LOGGER::xyz() aufgerufen, aber man kann der "instanzlosen LOGGER instanz" vars hinzufügen und irgendwo in einer klasse wieder abrufen per getter() und setter(), denn der getter und setter sieht so aus:


CODE Class LOGGER {

function setMyVar($myVar) {
LOGGER::setStaticVar($myVar,"MY_VAR"); // ruft methode zum statischen speichern auf
}

function getMyVar() {
return LOGGER::getStaticVar("MY_VAR"); // ruft methode zum abrufen einer statischen variable auf
}

// speichert variable in $GLOBALS, welches während der ganzen laufzeit vorhanden ist
function setStaticVar($varValue,$varName) {
$GLOBALS["_transient"]["LOGGER"][$varName] = $varValue;
}

// ruft eine per setStaticVar(...) gesetzte variable aus $GLOBALS ab.
function getStaticVar($varName) {
return $GLOBALS["_transient"]["LOGGER"][$varName];
}
}

ich weiss nicht, obs jetzt ein bisschen klarer ist, sonst werd ich's dir bei einem etwaigen treffen mal etwas genauer erklären.
rolleyes.gif
 
Zurück
Oben