Christoph Schnauß: "public static" in PHP 4.x und PHP 5.x

hallo Forum,

ich habe den Ansatz dieser Frage zwar bereits in meinem Thread https://forum.selfhtml.org/?t=143074&m=929313 angesprochen, so daß jemand, der sehr streng sein wollte, sofort "Doppelposting" schreien dürfte. Allerdings hat sich der Thread sehr schnell thematisch anders entwickelt.

Mir geht es um folgendes: ich habe in einem PHP-basierten Projekt (jaja, es ist ein technischer Revisionsentwurf meiner eigenen Seite) mit dem Vorlagensystem Smarty experimentiert - und erfolgreich experimentiert. Also habe ich (fast) alle Projektfiles auch hochgeladen. Funktioniert.

ABER: auf meinem eigenen Rechner verwende ich einen Apache 2.2.3 und wahlweise PHP 5.x oder eine Developer-Version (PHP 6.x). Der Provider stellt einen Apache 1.3.34 und PHP 4.4.4 zur Verfügung. Meine PHP-Scripts, in denen ich manche PHP-Funktionen als "private", manche als "public" oder als "public static" gekennzeichnet hatte, laufen lokal damit auch völlig zufriedenstellend. Die online-Fassung meckerte aber andauernd, so daß ich schließlich erstmal alle "public" usw. streichen mußte. Damit läuft es auch beim Provider.

Aber damit läuft es lokal bei mir nicht mehr. Ich bekomme beispielsweise, wenn ich mein Gästebuchscript laufen lasse, lokal erstmal eine Meckerei: "<b>Strict Standards</b>:  Non-static method Formular::gaestebuch() should not be called statically, assuming $this from incompatible context in <b>G:\phpseite\basis\Vorlagen.class.php</b> on line <b>234</b><br />" - die angemeckerte Zeile sieht so aus:
  function Gaestebuch() {Formular::gaestebuch();exit;}
Das heißt, sie ruft eine Funktion aus einer anderen (Klassen-)Datei auf, und in der steht wiederum:
  public function gaestebuch() { ... }
Bei meiner Seitenkonstruktion hat das übrigens den Effekt, daß durch die Meckerei ein horizontaler Scrollbalken entsteht (in Opera). Die Fehlermeldung steht nur im Quelltext, aber _vor_ der DOCTYPE-Deklaration.

Mit PHP 4.4.4 bei der online gestellten Fassung passiert das nicht.

Ich habe nun sowieso etwas Verständigungsprobleme, was die Verwendung solcher Angaben wie "public" oder "private" angeht und finde dazu übrigens auch im Handbuch keine ausreichende Erklärung (aber da hab ich in den letzten Tagen vielleicht nur nicht die richtigen Suchbegriffe probiert). Ich korrigiere das, wenn es eine Meckerei gibt, dann ist es wieder gut, aber man möchte ja gleich Code schreiben, der keinen Anölaß zu derlei Meckereien gibt. Kurz: wann und warum sind solche Bezeichnungen als "private" oder "public static" für Funktionen sinnvoll?

Grüße aus Berlin

Christoph S.

--
Visitenkarte
ss:| zu:) ls:& fo:) va:) sh:| rl:|
  1. Hallo Christoph.

    Kurz: wann und warum sind solche Bezeichnungen als "private" oder "public static" für Funktionen sinnvoll?

    private: Wenn die jeweilige Klassenmethode einzig und allein innerhalb der Klasse verwendet werden soll/darf.

    public static: Wenn die jeweilige Klassenmethode auch von außerhalb und ohne Instantiierung verwendet werden soll/darf.

    Meine Erklärungen fußen jedoch lediglich auf die Definitionen von „private“ und „public static“. Dass heißt, dass genau das gleiche auch noch einmal im Handbuch steht.

    Einen schönen Mittwoch noch.

    Gruß, Mathias

    --
    ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
    debian/rules
  2. hi,

    Ich habe nun sowieso etwas Verständigungsprobleme, was die Verwendung solcher Angaben wie "public" oder "private" angeht und finde dazu übrigens auch im Handbuch keine ausreichende Erklärung

    Die Erläuterungen zur Sichtbarkeit von Methoden und Attributen reicht dir nicht aus?

    Das Konzept der unterschiedlichen Sichtbarkeiten wurde übrigens AFAIK erst mit Version 5 eingeführt, PHP 4 kannte das noch gar nicht.
    In so fern ist die Diskrepanz zwischen der lokal zum Entwickeln und der "online" vorhandenen Version wohl keine sonderlich glückliche und geschickte Wahl. (Oder die des Providers. PHP 5 sollte m.E. heute das mindeste sein.)

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. hallo,

      Die Erläuterungen zur Sichtbarkeit von Methoden und Attributen reicht dir nicht aus?

      Doch. Ich habe sie bloß entweder nicht gefunden oder überlesen. Außerdem: man geht ja im Handbuch erst dann suchen, wenn es irgendein Problem gibt. Danke für den Link.

      Das Konzept der unterschiedlichen Sichtbarkeiten wurde übrigens AFAIK erst mit Version 5 eingeführt, PHP 4 kannte das noch gar nicht.

      Genau _das_, also eine solche Erläuterung, ab welcher PHP-Version ich das nutzen kann oder sogar muß, ist der Hintergrund meiner Fragestellung.

      In so fern ist die Diskrepanz zwischen der lokal zum Entwickeln und der "online" vorhandenen Version wohl keine sonderlich glückliche und geschickte Wahl. (Oder die des Providers. PHP 5 sollte m.E. heute das mindeste sein.)

      Naja, über den Provider soll hier nicht gestritten werden, zumindest wollte ich das nicht anzetteln. Ich bin allerdings überzeugt, daß es eine Menge Provider gibt, die nach wie vor Apache 1.3.x einsetzen und auch PHP 4.x - aus vermutlich bei ihnen fundierten Gründen. Und da kann es schonmal passieren, daß auch andere Bastler auf genau dasselbe Problem stoßen. Lokal mit PHP 5.x funktioniert alles prima, online beim Provider gibts Fehlermeldungen. Oder umgekehrt.

      Grüße aus Berlin

      Christoph S.

      --
      Visitenkarte
      ss:| zu:) ls:& fo:) va:) sh:| rl:|
      1. Hallo Christoph.

        Die Erläuterungen zur Sichtbarkeit von Methoden und Attributen reicht dir nicht aus?

        Doch. Ich habe sie bloß entweder nicht gefunden oder überlesen. Außerdem: man geht ja im Handbuch erst dann suchen, wenn es irgendein Problem gibt.

        Dann bin ich sicher nicht „man“. Ich konsultiere das PHP-Handbuch unter anderem wenn ich etwas Neues lernen möchte, nicht nur als Nachschlagewerk.

        Einen schönen Mittwoch noch.

        Gruß, Mathias

        --
        ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
        debian/rules
        1. hi,

          man geht ja im Handbuch erst dann suchen, wenn es irgendein Problem gibt.
          Dann bin ich sicher nicht „man“. Ich konsultiere das PHP-Handbuch unter anderem wenn ich etwas Neues lernen möchte, nicht nur als Nachschlagewerk.

          Was ist denn die Absicht, etwas Neues lernen zu wollen, anderes als ein Problem?

          Grüße aus Berlin

          Christoph S.

          --
          Visitenkarte
          ss:| zu:) ls:& fo:) va:) sh:| rl:|
          1. Hallo Christoph,

            Was ist denn die Absicht, etwas Neues lernen zu wollen, anderes als ein Problem?

            Neugier definierst du also als Problem? OK, wenn sie übertrieben ist, kann es durchaus mal problematisch werden, aber in diesem Fall kann davon nicht die Rede sein.

            Beste Grüße
            Richard

            1. hallo,

              Was ist denn die Absicht, etwas Neues lernen zu wollen, anderes als ein Problem?
              Neugier definierst du also als Problem?

              Nein.

              Aber na gut, wenn wir denn wirklich philosophisch werden wollen: die Absicht, irgendetwas lernen oder kennenlernen zu wollen, beruht darauf, daß das, was kennengelernt werden soll, bereits als etwas Unbekanntes bewußt ist und damit problematisiert werden kann. Wir Menschen (und übrigens auch allerhand andere Säugetiere und andere Lebensformen) lernen zwar jeden Tag irgendwas - aber das muß uns "zustoßen", es muß geschehen, es wird also nicht gesucht, und damit auch nicht problematisiert. Wir wissen in der Regel gar nicht, wieviele Probleme es geben könnte.  Wir knallen uns an Sommertagen auf irgendeinen Sandstrand und freuen uns über die korrekte Auswahl des Sonnenöls und die einsetzende Bräunung der Haut, ohne daran zu denken, daß das, was der Haut grade passiert, eigentlich ein "Problem" sein könnte. Erst wenn es die Presse und das Fernsehen verkünden, wird das Sonnenlicht, seine Verfügbarkeit und seine Wirkung ein Problem.
              Genauso bin ich mit PHP verfahren. Und erst als es mir die "Presse" - also die Fehlermeldung im Browser - deutlich ins Bewußtsein gerückt hat, bin ich auf die Suche nach den Ursachen dafür gegangen.

              aber in diesem Fall kann davon nicht die Rede sein.

              Doch, gerade in diesem Fall. Meinst du denn, ich hätte das PHP-Handbuch nicht schon ein paarmal von vorn bis hinten durchgeklickert? Auch ohne Fehlermeldung bin ich natürlich ein paarmal durch die Seiten zur OOP marschiert - aber mit ganz anderer Aufmerksamkeit. Das "Problem" war, daß ich wissen wollte, wie das nun mit der OOP in PHP geht. Und zugleich war das das "Neue", was ich lernen wollte. Es stand da auch was dazu drin, daß ich eben solche Angaben wie "static", "public" usw. verwenden kann, sehr gut, das habe ich ja erstmal gemacht. Und funktionierte auch.
              Nach dem Upload funktionierte "es" aber beim Provider nicht mehr. Das war nun gleichzeitig etwas "Neues" wie auch ein unvorhergesehenes "Problem". Liegt dann die Analogie nicht doch sehr nahe?

              Im übrigen hatte ich im Ausgangsposting angegeben, daß meine Suchbegriffe möglicherweise nicht treffend genug formuliert waren. wahsaga hat das auf ungewohnt "sanfte" Weise mit der Angabe eines Verweises beantwortet, und hilfreich beantwortet - ich bin halt einfach nicht auf die Idee gekommen, daß ich im zweiten Suchfeld der PHP-Handbuchsuche doch mal die Standard-Vorgabe "functions list" durch "online documentation" ersetzen müßte. Das hat mir wahsaga mitgeteilt, ohne es explizit angeben zu müssen.

              Du siehst: es braucht auch ein klitzekleines bißchen Übung, den "Kontext" von Forumspostings zu lesen ;-)

              Grüße aus Berlin

              Christoph S.

              --
              Visitenkarte
              ss:| zu:) ls:& fo:) va:) sh:| rl:|
          2. Hallo Christoph.

            man geht ja im Handbuch erst dann suchen, wenn es irgendein Problem gibt.
            Dann bin ich sicher nicht „man“. Ich konsultiere das PHP-Handbuch unter anderem wenn ich etwas Neues lernen möchte, nicht nur als Nachschlagewerk.

            Was ist denn die Absicht, etwas Neues lernen zu wollen, anderes als ein Problem?

            Der Wille, etwas zu verbessern? Der Gedanke, dass es für $vorgang vielleicht effizientere Lösungswege geben könnte?

            Einen schönen Mittwoch noch.

            Gruß, Mathias

            --
            ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
            debian/rules
      2. Hallo Christoph,

        In so fern ist die Diskrepanz zwischen der lokal zum Entwickeln und der "online" vorhandenen Version wohl keine sonderlich glückliche und geschickte Wahl.

        da stimme ich wahsaga voll und ganz zu. Deswegen auch ein "fachlich hilfreich".

        Naja, über den Provider soll hier nicht gestritten werden, zumindest wollte ich das nicht anzetteln. Ich bin allerdings überzeugt, daß es eine Menge Provider gibt, die nach wie vor Apache 1.3.x einsetzen und auch PHP 4.x - aus vermutlich bei ihnen fundierten Gründen. Und da kann es schonmal passieren, daß auch andere Bastler auf genau dasselbe Problem stoßen. Lokal mit PHP 5.x funktioniert alles prima, online beim Provider gibts Fehlermeldungen. Oder umgekehrt.

        In vielen Fällen funktioniert es nicht, sondern es funzt[tm] nur :-) Neben den schon recht großen Unterschieden, was die Fähigkeiten der verschiedenen PHP-Releases angeht, ist insbesondere MySQL ein guter Kandidat für "funktioniert nicht mehr". Um etwas zu lernen, dafür ist XAMPP gut geeignet, dafür kannst Du auch brandaktuelle apache-, PHP- oder MySQL-Versionen verwenden.

        Wenn es jedoch um ein einzelnes konkretes Projekt geht, ist es eine ganz hervorragende Idee, die Entwicklungsumgebung möglichst nahe an die Providerumgebung anzupassen. Dies gilt, wie bereits bemerkt, ganz besonders für PHP und noch mehr für MySQL. Wie ist meine Lieblingsgegenfrage bei Fragen zu MySQL hier im Forum ...

        Warum Du dies nicht tust, das verstehe ich nicht. Wirklich nicht. Dein Faible für Virtuelle Maschinen, für Betriebssysteme, für Installationen macht es Dir doch leicht. Warum nicht eine virtuelle Maschine mit (in etwa) der Umgebung des Providers, z.B. gleiche apache-Version, gleiche PHP-Version, annähernd gleiche PHP-Konfiguration, gleiche MySQL-Version, idealerweise unter dem gleichen Betriebssystem?

        Wenn Du auf bestimmte alte Versionen und ihre "Features" keine Rücksicht mehr nehmen willst (was ich ja verstehen kann), dann solltest Du bei der Auswahl Deines Providers darauf achten, dass Du das nicht mehr nötig hast oder den Provider davon überzeugen, dass es nicht mehr nötig sein wird. Dass "Bastler" immer wieder auf solche Probleme stoßen, sei es PHP- oder sei es MySQL-bezogen, füllt dieses Forum täglich aufs Neue.

        Freundliche Grüße

        Vinzenz

        1. hallo Vinzenz,

          In so fern ist die Diskrepanz zwischen der lokal zum Entwickeln und der "online" vorhandenen Version wohl keine sonderlich glückliche und geschickte Wahl.
          da stimme ich wahsaga voll und ganz zu. Deswegen auch ein "fachlich hilfreich".

          Öhm ... ja, der Sinn ist hilfreich, aber der eigentliche Satzbau nicht (hihi, ich finde ja doch noch was). Eine "Diskrepanz" kann man leider nicht wählen. Sie tritt allerdings gelegentlich auf.

          Warum nicht eine virtuelle Maschine mit (in etwa) der Umgebung des Providers, z.B. gleiche apache-Version, gleiche PHP-Version, annähernd gleiche PHP-Konfiguration, gleiche MySQL-Version, idealerweise unter dem gleichen Betriebssystem?

          Naja, jetzt, wo du das sagst, finde ich auch, daß ich das hätte tun sollen. Nein, es ist für mich überhaupt kein Problem, binnen einer Stunde einen perfekten "mirror" mit demselben Betriebssystem, Apache und PHP als virtuelle Maschine einzurichten. Die Provider, die ich nutze, verwenden glücklicherweise keine SUSE ... *g*

          Wenn Du auf bestimmte alte Versionen und ihre "Features" keine Rücksicht mehr nehmen willst (was ich ja verstehen kann), dann solltest Du bei der Auswahl Deines Providers darauf achten, dass Du das nicht mehr nötig hast oder den Provider davon überzeugen, dass es nicht mehr nötig sein wird.

          Hm. Naja. Eigentlich will ich ja auch keine Rücksicht mehr nehmen, und mit dem Provider, der meine Domain hostet, könnte ich mich jederzeit verständigen - egal worüber. Aber ich hatte ja erstmal eine Probeversion zum Ausprobieren online gestellt, und das liegt nun bei einem anderen Provider. Der wäre zwar generell auch zu allerhand Verständigungen bereit. Ich wußte halt bis vor drei Tagen nicht, daß eine solche "Verständigung" nötig werden könnte.

          Dass "Bastler" immer wieder auf solche Probleme stoßen, sei es PHP- oder sei es MySQL-bezogen, füllt dieses Forum täglich aufs Neue.

          Aua :-(

          Grüße aus Berlin

          Christoph S.

          --
          Visitenkarte
          ss:| zu:) ls:& fo:) va:) sh:| rl:|
  3. Hallo Christoph,

    ABER: auf meinem eigenen Rechner verwende ich einen Apache 2.2.3 und wahlweise PHP 5.x oder eine Developer-Version (PHP 6.x). Der Provider stellt einen Apache 1.3.34 und PHP 4.4.4 zur Verfügung. Meine PHP-Scripts, in denen ich manche PHP-Funktionen als "private", manche als "public" oder als "public static" gekennzeichnet hatte, laufen lokal damit auch völlig zufriedenstellend. Die online-Fassung meckerte aber andauernd, so daß ich schließlich erstmal alle "public" usw. streichen mußte. Damit läuft es auch beim Provider

    Ja, das liegt daran, dass PHP 4 mit public, private (und protected) nichts anfangen kann, weil sie mit PHP 5 eingeführt wurden. Siehe auch Appendix B. Migrating from PHP 4 to PHP 5.

    Aber damit läuft es lokal bei mir nicht mehr. Ich bekomme beispielsweise, wenn ich mein Gästebuchscript laufen lasse, lokal erstmal eine Meckerei: "<b>Strict Standards</b>:  Non-static method Formular::gaestebuch() should not be called statically, assuming $this from incompatible context in <b>G:\phpseite\basis\Vorlagen.class.php</b> on line <b>234</b><br />" - die angemeckerte Zeile sieht so aus:

    Ja, denn statische Methoden gab es schon in PHP 4. Wenn du Methoden über den Klassennamen aufrufst und nicht über ein konkretes Objekt, müssen diese Methoden statisch sein.

    Ich habe nun sowieso etwas Verständigungsprobleme, was die Verwendung solcher Angaben wie "public" oder "private" angeht und finde dazu übrigens auch im Handbuch keine ausreichende Erklärung (aber da hab ich in den letzten Tagen vielleicht nur nicht die richtigen Suchbegriffe probiert).

    * public - Hierauf kann von überall zugegriffen werden
    * private - Diese Methode kann nur von innerhalb der Klasse angesprochen werden
    * protected - Diese Methode ist nur innerhalb der Klasse und in von ihr abgeleiteten Unterklassen sichtbar

    Ich korrigiere das, wenn es eine Meckerei gibt, dann ist es wieder gut, aber man möchte ja gleich Code schreiben, der keinen Anölaß zu derlei Meckereien gibt. Kurz: wann und warum sind solche Bezeichnungen als "private" oder "public static" für Funktionen sinnvoll?

    Wenn du sicher sein kannst, dass dein Code nicht mehr unter PHP 4 laufen muss ;-)

    Schöne Grüße,

    Johannes

  4. echo $begrüßung;

    ABER: auf meinem eigenen Rechner verwende ich [...] PHP 5.x [...] Der Provider [...] PHP 4.4.4 [...]. Meine PHP-Scripts, in denen ich manche PHP-Funktionen als "private", manche als "public" oder als "public static" gekennzeichnet hatte, laufen lokal damit auch völlig zufriedenstellend. Die online-Fassung meckerte aber andauernd, so daß ich schließlich erstmal alle "public" usw. streichen mußte. Damit läuft es auch beim Provider.

    (Sichtbarkeitsmodifikatoren kommen nur im Zusammenhang mit Klassen vor. Funktionen werden in Klassen aber Methoden genannt, um sie auch sprachlich von nicht-klassengebundenen Funktionen abzuheben.)

    Wenn du ein Klassen verwendendes Script so schreibst, dass die neuen PHP5-Features in der reinen PHP5-Art verwendet, dann läuft, wie du bemerkt hast, es unter PHP 4 nicht mehr. Schreibst du es PHP4-kompatibel entspricht das nicht mehr in jedem Fall dem neuen PHP5-Klassen-Konzept. Möchtest du dennoch PHP4-kompatible Klassen unter PHP5 einsetzen, solltest du E_STRICT ausschalten, ...

    "<b>Strict Standards</b>:  Non-static method Formular::gaestebuch() should not be called statically, assuming $this from incompatible context [...]

    ... damit unter anderem solche Meldungen nicht mehr auftauchen.

    die angemeckerte Zeile sieht so aus:
      function Gaestebuch() {Formular::gaestebuch();exit;}
    Das heißt, sie ruft eine Funktion aus einer anderen (Klassen-)Datei auf, und in der steht wiederum:

    (Die richtigere Terminologie wäre: Sie ruft eine statische Klassenmethode auf.) Methoden, die statisch aufgerufen werden sollen, müssen, um E_STRICT-kompatibel zu sein, als static gekennzeichnet werden. Unter PHP4 war es egal, ob eine Methode dynamisch (à la $this->methode()) oder statisch (à la klasse::methode()) aufgerufen wurde. PHP5 will nur noch eine von beiden Aufrufarten und das auch so gekennzeichnet haben, um E_STRICT-kompatibel zu sein.

    echo "$verabschiedung $name";

    1. hallo,

      Das heißt, sie ruft eine Funktion aus einer anderen (Klassen-)Datei auf, und in der steht wiederum:
      (Die richtigere Terminologie wäre: Sie ruft eine statische Klassenmethode auf.)

      Hm. Hört sich überzeugend an.

      Methoden, die statisch aufgerufen werden sollen, müssen, um E_STRICT-kompatibel zu sein, als static gekennzeichnet werden. Unter PHP4 war es egal, ob eine Methode dynamisch (à la $this->methode()) oder statisch (à la klasse::methode()) aufgerufen wurde. PHP5 will nur noch eine von beiden Aufrufarten und das auch so gekennzeichnet haben, um E_STRICT-kompatibel zu sein.

      Genau das scheint mir noch nicht ganz klar zu sein. Ich habe nun versucht, den kram in eine Bedingungsabfrage (if/else) zu packen, allerdings beseitigt das die Fehlermeldung nicht.

      Grüße aus Berlin

      Christoph S.

      --
      Visitenkarte
      ss:| zu:) ls:& fo:) va:) sh:| rl:|
      1. echo $begrüßung;

        Methoden, die statisch aufgerufen werden sollen, müssen, um E_STRICT-kompatibel zu sein, als static gekennzeichnet werden. Unter PHP4 war es egal, ob eine Methode dynamisch (à la $this->methode()) oder statisch (à la klasse::methode()) aufgerufen wurde. PHP5 will nur noch eine von beiden Aufrufarten und das auch so gekennzeichnet haben, um E_STRICT-kompatibel zu sein.

        Genau das scheint mir noch nicht ganz klar zu sein. Ich habe nun versucht, den kram in eine Bedingungsabfrage (if/else) zu packen, allerdings beseitigt das die Fehlermeldung nicht.

        Unter PHP4 durfte man bei der Verwendung von Objekten schludern. Methoden durften sowohl statisch als auch über Instanzen aufgerufen werden. PHP5 ist da etwas strenger geworden. Diese Strenge kann man aber durch E_STRICT aus- und einschalten.

        Seit PHP 4 wird der Quelltext vollständig geparst und erst dann ausgeführt. Es ist damit nicht mehr möglich, Syntax-"Fehler" in einer bedingten Anweisung zu verbergen. Das geht nur, wenn du den zweifelhaften Quelltext auslagerst und bedingt inkludierst. Aber: Klassendeklarationen können nicht geteilt werden, sie müssen sich in einer Datei befinden. Man könnte aber mit Vererbung das Problem zu lösen versuchen.

        Der ganze Aufwand läuft dann darauf hinaus, mehr oder weniger zwei Versionen pflegen zu müssen. Doch wozu der Aufwand? Verzichte auf PHP4 oder auf E_STRICT.

        echo "$verabschiedung $name";