PHP Statischen Aufruf erkennen

Brabax

New member
#1
Moinsen!

Gibt es in PHP die Möglichkeit zu erkennen ob die Methode einer Klasse statisch oder über ein Objekt aufgerufen wurde?

Könnte man das überprüfen in dem man schaut ob eine Eigenschaft gesetzt wurde im Sinne von isset($this->Eigenschaft), oder gibt es da einen besseren Weg?

lG

Brabax
 
#2
Nicht wirklich. Aber du kannst prüfen, ob die Methode in einem statischen Kontext ausgeführt wird oder nicht.

PHP:
<?php

class Foo
{
    public static function static_function() {
        $isStatic = !(isset($this) && get_class($this) == __CLASS__)
        echo var_dump($isStatic);
    }
    
    public function non_static_function() {
        $isStatic = !(isset($this) && get_class($this) == __CLASS__)
        echo var_dump($isStatic);
    }
}

$foo = new Foo();
$foo->static_function();
$foo->non_static_function();

Foo::static_function();
Foo::non_static_function();

?>
 

odigo

Member of Honour
#4
Also ich kenn mich mit OOP in PHP null aus. Ich versuchs mal mit OOP-Theorie: Du könntest doch einen Standardconstructor in der Klasse definieren der ein Flag setzt. Ist das Flag nicht gesetzt muss es wohl ein static-Aufruf gewesen sein.

Für was will man sowas eigentlich wissen, wenn ich fragen darf?
 

GrafZahl

Member of Honour
#5
$this ist nicht gesetzt falls der aufruf ohne ein bezugsobjekt erfolgt ist ...

das ganze oo konzept von php ist sowieso käse ...

php unterscheidet nur zwischen einem objektbezogenen aufruf, und einem nicht objekt bezogenen aufruf ... der witz daran: das objekt auf das sich der aufruf bezieht muss nicht zur klasse gehören in der die funktion deffiniert wurde ...
 

Brabax

New member
#6
Ich war vorhin am Programmieren und war gerade dabei eine Methode zu entwickeln, die sich sowohl als statische als auch als Objektmethode anbot. Über ein Objekt, war das Argument für die Methode bereits vorher als Eigenschaft festgelegt und bei einem statischen Aufruf hätte man eben die Möglichkeit gehabt, eine Alternative für das Argument zu liefern.

Da ich zu faul war diese Methode zweimal zu schreiben, habe ich mir überlegt, ob das wohl funktioniert und bin dann bei Google leider nicht schlau geworden.

Im Endeffekt habe ich mich entschlossen, dass ich einen statischen Aufruf einfach ausschließe (wäre quasi nur ein unsauberes Komfort-Ding für faule Brabaxen gewesen), aber die Frage hat mich halt trotzdem beschäftigt, gerade weil PHP ja oftmals sehr viel Freiraum bietet, die Programmiersprache nach Belieben zu misshandeln. :)

Ist in diesem Sinne dann auch mehr theoretischer Natur. :)

lG

Brabax

Edit:

das ganze oo konzept von php ist sowieso käse ...
Dient imo wahrscheinlich auch nur der besseren Strukturierung :)
 

GrafZahl

Member of Honour
#7
Dient imo wahrscheinlich auch nur der besseren Strukturierung
PHP:
class Foo
{

    public function upsi()
    {
        echo var_dump($this);
        echo "\n";
    }

}

class Bar
{

    public function whoopsi()
    {
        Foo::upsi();
    }

}


Foo::upsi();
Bar::whoopsi();
$foo=new Foo;
$bar=new Bar;

$foo->upsi();
$bar->whoopsi();
ausgabe:
Code:
NULL

NULL

object(Foo)#1 (0) {
}

object(Bar)#2 (0) {
}
wieviel struktur steckt darin?

die "this" referenz zeigt auf den objektbezug ... ist dieser nicht gegeben, zeigt sie auf NULL (ist eigentlich nicht existent, aber in php hat ja so ziemlich alles einen wert ... es muss nichtmal existieren...)

was daran so schwer sein soll statische member sichtbarkeit von instanz member sichtbarkeit zu trennen weiß ich nicht ...

was mir allerdings schwerer im magen liegt, ist die tatsache, dass es möglich ist einer methode etwas im objekt-kontext unterzujubeln, das nichtmal zu ihrer klasse gehört ... aber es ist eben nur ein objekt kontext ... niemand sprach von einem instanz bezogenen kontext ...

ich habe versucht darin struktur zu suchen ... ich finde keine ... was bringt ein oo konzept, wenn es nicht mal den hauch von typisierung gibt? ... ja, toll, ich kann dinge vererben ... man kann einen hauch von polymorphie damit erzeugen, aber eine methode kann sich nicht darauf verlassen, dass sie nur auf instanzen ihrer klasse ausgeführt wird...

bitte entschuldigt mich nun, ich beiß an dieser stelle mal in die tischkante oder so ...:wall:
 

benediktibk

Standardgruppe für nicht aktivierte User
#8
Sorry, ich habe keine Ahnung von PHP, aber: Wird da wirklich upsi mit einer Instanz auf Bar (als this) ausgeführt?
Ultimate Fail! :D
 

metax.

New member
#9
Klar, hier ist PHP ziemlich unsauber (wie auch in vielen anderen Bereichen).
Aber ich sehe nicht, wo dein Problem ist, wenn du statische Methoden immer statisch aufrufst (ohne einen Bezug auf $this) und nichtstatische Methoden immer über den -> Operator (und nicht mit dem Paamayim Nekudotayim Operator).
Ich behaupte mal, wenn man es nicht darauf anlegt, verhält sich OOP in PHP auch nicht so ungewöhnlich ...
 

GrafZahl

Member of Honour
#10
wenn man sich von vorne herein daran hält, mag man diesen und andere makel ignorieren können, aber sinn und zweck von kapselung ist beispielsweise bestimmte zugriffspfade einzuhalten ...

php verfolgt an dieser stelle das motto, "wir haben zwar einen tresor für wertvolle dinge, aber der ist grundsätzlich nicht abgeschlossen und sperrangelweit offen, weil diebstahl ja verboten ist ..."

das man im zweifel überall dran kommt, ist klar ...
das man sich an bestimmte regeln bei der entwicklung halten sollte ist auch klar ...

aber php führt das ganze ad absurdum, wenn nichtmal das sprachkonstrukt eine grundlegende trennung zwischen klassen hinbekommt ... ducktyping hin oder her, ein objekt sollte seine methoden kennen, eine methode sollte die klasse des objekts kennen auf dem sie opperiert, und es macht mal so überhaupt keinen sinn aus oo sicht wenn eine nicht statische methode einer klasse mit einem objekt aufgerufen wird, wohlgemerkt nicht als parameter sondern als verweis auf das objekt in dessen kontext die methode aufgerufen wurde, das einer völlig anderen klasse angehört, die keinerlei vererbungsbeziehung zur deffinierenden klasse hat.

im übrigen scheint es php reichlich egal zu sein, wie die sichtbarkeit der methode deffiniert wurde ...

in meinem beispiel als "public function" ist die methode als nicht statisch deklariert

aus kompatiblitätsgründen mit php4 wäre die deklaration als "function" dagegen implitiz "public static function" ... bei solchen legacy konstrukten kann ich es ja noch halbwegs nachvollziehen, das etwas unsauber ist weil man an altlasten gebunden ist ...

aber das grundlegende konzept das php als oo konzept fährt ist so schwammig wie der rest der sprache ... man unterscheidet 2 arten von kontexten statisch und objekt bezogen ... das gibt es bei c++ und co auch? VORSICHT ... dem ist nicht so ... sprachen wie c++,java und co unterscheiden hier statische kontexte, und instanz bezogene kontexte, soll heißen instanzen einer klasse teilen sich den satz an nicht statischen methoden ihrer klasse, und diese methoden sind nur für diese instanzen deffiniert ... allenfalls noch für instanzen von klassen die von der deffinierenden klasse erben. das ist einer der wesentlichen punkte einer sauberen oo sprachdefinition ...

theoretisch müssten alle deine php funktionen vor der benutzung von $this die klassenzugehörigkeit prüfen ... ist das logisch? welchen sinnvollen nutzen hat diese aufweichung des etablierten oo konzepts?
 

rami

New member
#11
DAS ist fail, das stimmt.

die "this" referenz zeigt auf den objektbezug ... ist dieser nicht gegeben, zeigt sie auf NULL (ist eigentlich nicht existent, aber in php hat ja so ziemlich alles einen wert ... es muss nichtmal existieren...)
Das wiederrum ist falsches Bashing. Es hat keinen Wert und existiert nicht. NULL ist die grafische Darstellung von var_dump von nicht existenten Variablen. null bedeutet, dass die Variable nicht existiert. Es ist an sich kein Wert.

PHP:
<?php
$nichtexistent = null;
var_dump(isset($nichtexistent));

$foo = "bar";
unset($foo);
var_dump($foo);

/* Output:

bool(false)
NULL
*/
 

GrafZahl

Member of Honour
#12
Das wiederrum ist falsches Bashing. Es hat keinen Wert und existiert nicht. NULL ist die grafische Darstellung von var_dump von nicht existenten Variablen. null bedeutet, dass die Variable nicht existiert. Es ist an sich kein Wert.
NULL ist keine "graphische" darstellung ... es ist der semantische begriff für "nichts" ... die tatsache dass etwas zu NULL evaluiert wird, das nicht deffiniert ist stört mich hier...

das php nicht typsicher ist, ist eine sache ... aber es ist eine andere, dass grundlegend alles was nicht deffiniert ist zu NULL evaluiert wird ...

du greifst auf etwas zu und erhälst die aussage, dass es keinen wert besitzt (=NULL) ... ganz egal ob das worauf du zugreifst überhaupt existiert oder nicht ... rein von der logik passt das nicht ... auf dinge die nicht existieren, sollte nicht zugegriffen werden können ... wenn sie existieren, haben sie entweder einen wert, oder ggf. eben nicht (=NULL) ...

so wie es ist, ist es eine macke im design der sprache, die das potential zur fehlerquelle hat

klar funktioniert es, und es ist auch nicht diese eine macke die aus php eine schwammige, unscharfe sprache macht, aber es kommt eines zum anderen ...
 
#13
Moin!

NULL ist keine "graphische" darstellung ... es ist der semantische begriff für "nichts" ... die tatsache dass etwas zu NULL evaluiert wird, das nicht deffiniert ist stört mich hier...
var_dump ist doch aber auch nur eine Funktion mit entsprechenden Rückgabewerten.
Ist es dann nicht sehr wahrscheinlich, dass man es sich hier mit den Rückgabewerten einfach gemacht und gesagt hat, dass eine nichtexistente Variable ganz einfach "NULL" als Rückgabewert enthält?

lG

Brabax
 

beavisbee

Member of Honour
#15
das php nicht typsicher ist, ist eine sache ... aber es ist eine andere, dass grundlegend alles was nicht deffiniert ist zu NULL evaluiert wird ...

du greifst auf etwas zu und erhälst die aussage, dass es keinen wert besitzt (=NULL) ... ganz egal ob das worauf du zugreifst überhaupt existiert oder nicht ... rein von der logik passt das nicht ...
Natürlich passt das von der Logik her:
Da in PHP keine Variablen-Deklaration nötig ist, ist es auch schwer, von "existiert nicht" zu reden... Die Variable existiert ab dem Moment, wo sie genutzt wird - und wenn sie keinen Wert hat, ist sie NULL.

Und wenn man (was man in seiner Entwicklungs-/Test-Umgebung immer machen sollte) error_reporting auf E_ALL stellt, dann haut PHP auch 'ne Warnung bzw. Notice raus, wenn man z.B. nicht deklarierte Variablen lesen will oder einem noch nicht deklariertem Array Werte anhängen möchte,... somit geht man sicher, dass man keine unnötigen Fehlerquellen einbaut.

Ich gebe dir Recht, dass PHP vom Design her vielleicht mehr (okay: vielleicht auch wesentlich mehr) potentielle Fehlerquellen bietet, als es manch andere Sprache tut. Aber was du hier veranstaltest, ist echt einfach nur Sprach-Bashing.

"OOP" in PHP4 war wirklich Murks, OOP in PHP5 hat sicherlich noch so seine kleinen Eigenheiten, aber auch viel Potential (also ich code gerne und viel OOP in PHP5) - schauen wir mal, wie sich das ganze in PHP6 weiterentwickelt...
 
Oben