borisbaer: PHP-Framework funktioniert nicht auf dem STRATO-Server

problematische Seite

Hi,

mein Framework, das auf dem lokalen Server wunderbar dargestellt wird, spuckt seltsame Fehlermeldungen auf dem STRATO-Server aus.

Meine Vermutung war, dass auf einem Linux-Server die Groß- und Kleinschreibung relevant ist und vermutlich deshalb irgendetwas nicht erkannt wird. Das Problem hatte ich schon mal. Ich habe daraufhin alle PHP-Dateien, die eine Klasse enthalten, mit einem Großbuchstaben beginnen lassen, damit sie genau mit den Namespaces übereinstimmen, doch trotzdem funktioniert es nicht (auch die Ordner hatte ich geändert, aber wenn ich z.B. den Core-Ordner mit einem Großbuchstaben schreibe, bekomme ich einen Totalausfall auf dem Server (HTTP 500). Mein Projekt-Ordner sieht so aus:

Ich hoffe, man kann es lesen. Jedenfalls bin ich mit meinem Latein am Ende. Ich bitte um Hilfe!

Grüße
Boris

akzeptierte Antworten

  1. problematische Seite

    Hi,

    mein Framework, das auf dem lokalen Server wunderbar dargestellt wird, spuckt seltsame Fehlermeldungen auf dem STRATO-Server aus.

    Hi Boris,

    was ist denn an der Fehlermeldung seltsam?
    Sie sagt doch genau, in welchem script an welcher Stelle was erwartet wird und was Du der php-Funktion stattdessen gibst.

    Ich vermute, dass Du lokal noch auf php7 arbeitest und php8 auf Deinem Server (8.1.9, wie ich sehe) da etwas nicht akzeptiert, was in php7 noch durchging. Habe zwar keine Änderung der Funktion selber seit php8 gelesen, aber sowas in der Art könnte ich mir denken. Leerstring, leeres Array, o.ä. (Fehlermeldung sagt, Du übergibst einen Boolwert)

    Überprüfe den 2. Parameter Deines str_replace() in deiner view.php. Das muss ein String oder ein Array sein, ist es aber bei Dir nicht (zumindest in diesem Fall).

    Jörg

    1. problematische Seite

      Hi Jörg,

      was ist denn an der Fehlermeldung seltsam?
      Sie sagt doch genau, in welchem script an welcher Stelle was erwartet wird und was Du der php-Funktion stattdessen gibst.

      ja, das ist aber ganz seltsam, denn der Code sieht an dieser Stelle so aus: return str_replace( '{ main }', $view, $layout ); Und wenn ich ein var_dump() auf $view und auf $layout anwende, dann gibt es mir aus, dass es sich hierbei um einen string handelt. Und der wird ja auch erwartet. Auf jeden Fall sollte es ich nicht um einen booleschen Wert handeln, wie die Fehlermeldung behauptet.

      Ich vermute, dass Du lokal noch auf php7 arbeitest und php8 da etwas nicht akzeptiert, was in php7 noch durchging.

      Lokal verwende ich laut phpinfo() PHP Version 8.1.4. Auf dem STRATO-Server ist PHP Version 8.1.9 installiert. Kein großer Unterschied.

      Überprüfe den 2. Parameter Deines str_replace in deiner view.php. Das muss ein String oder ein Array sein.

      Im Ganzen sieht der (relevante) Code in der View-Class folgendermaßen aus:

      class View {
      	public function getView(): string
      	{
      		foreach( $this -> params as $key => $value ) {
      			$$key = $value;
      		}
      
      		ob_start();
      		include "../app/views/layouts/default.php";
      		$layout = ob_get_clean();
      		include '../app/views/' . $this -> view . '.php';
      		$view = ob_get_clean();
      
      		return str_replace( '{ main }', $view, $layout );
      	}
      
      	public function __toString(): string
      	{
      		return $this -> getView(); 
      	}
      }
      

      Keine Ahnung, was hier schiefläuft, ehrlich gesagt, zumal es ja, wie gesagt, auf dem localhost ohne Probleme funktioniert …

      1. problematische Seite

        Kannst Du die Zeile

        return str_replace( '{ main }', $view, $layout );

        mal testhalber gegen

        return str_replace( '{ main }', "$view", $layout );

        austauschen?

        1. problematische Seite

          Hallo Jörg,

          Kannst Du die Zeile

          return str_replace( '{ main }', $view, $layout );

          mal testhalber gegen

          return str_replace( '{ main }', "$view", $layout );

          austauschen?

          wenn $view ein String ist, wie Boris überprüft hat, was soll das dann bringen?

          @borisbaer: Die PHP-Fehlermeldung sagt aber tatsächlich, dass $view ein bool ist. Das kann laut PHP-Handbuch sein, wenn Output Buffering nicht aktiv ist.
          Kann es sein, dass du vor dem zweiten ob_get_clean() auch ein zweites ob_start() notieren solltest? Aus dem Handbuch geht leider nicht eindeutig hervor, ob ob_get_clean() das Output Buffering beendet oder nicht.

          Einen schönen Tag noch
           Martin

          --
          Wer nicht genießt, wird ungenießbar.
          (Mottospruch auf einem T-Shirt)
          1. problematische Seite

            Hallo Martin,

            wenn $view ein String ist, wie Boris überprüft hat, was soll das dann bringen?

            Naja, ist mir auch schon passiert, dass ich etwas überprüft habe und es war dann letztlich etwas ganz anderes, was ich tatsächlich überprüft hatte.. Deshalb wollt ichs an der Stelle mal erzwingen. 😉
            Hier hats geholfen.

            @borisbaer: Die PHP-Fehlermeldung sagt aber tatsächlich, dass $view ein bool ist. Das kann laut PHP-Handbuch sein, wenn Output Buffering nicht aktiv ist.

            Das habe ich in dem Zusammenhang auch gelesen.

            Gruß, Jörg

          2. problematische Seite

            Hallo nochmal,

            @borisbaer: Die PHP-Fehlermeldung sagt aber tatsächlich, dass $view ein bool ist. Das kann laut PHP-Handbuch sein, wenn Output Buffering nicht aktiv ist.
            Kann es sein, dass du vor dem zweiten ob_get_clean() auch ein zweites ob_start() notieren solltest? Aus dem Handbuch geht leider nicht eindeutig hervor, ob ob_get_clean() das Output Buffering beendet oder nicht.

            doch, wenn man aufmerksam liest, ist das eindeutig: Angeblich ist ob_get_clean() äquivalent zu ob_get_contents() gefolgt von ob_end_clean(). Und letzteres beendet das Output Buffering.

            Einen schönen Tag noch
             Martin

            --
            Wer nicht genießt, wird ungenießbar.
            (Mottospruch auf einem T-Shirt)
        2. problematische Seite

          Kannst Du die Zeile

          return str_replace( '{ main }', $view, $layout );

          mal testhalber gegen

          return str_replace( '{ main }', "$view", $layout );

          austauschen?

          Das habe ich getan, und jetzt wird zumindest diese Fehlermeldung nicht mehr angezeigt und das Seiten-Layout wird ganz normal gerendert. Danke!

          Ich verstehe aber trotzdem nicht, was hier eigentlich das Problem war. Auf dem STRATO-Server ist’s ein bool, lokal ist’s ein string. Das kann doch irgendwie nicht sein. 😵

          Die Controller-Klassen werden aber leider immer noch nicht gefunden. Hier vermute ich stark, dass es etwas mit case sensitivity zu tun hat … oder? Habe hier aber schon alles Mögliche ausprobiert. Großschreibung nur der Dateien, dann nur der Ordner dann beides, dann alles klein usw. Es haut nicht hin.

          1. problematische Seite

            Die Controller-Klassen werden aber leider immer noch nicht gefunden. Hier vermute ich stark, dass es etwas mit case sensitivity zu tun hat … oder?

            • Zeig mal wie Du Deine Klassen lädst. Also (wohl) den Autoloader.
            • Dazu natürlich die Namespaces.
            • Strato? Da war doch was mit ungewöhnlichen Links bzw. Mounts. Möglicherweise muss irgendwo ein realpath($verzeichnis) hin.
            1. problematische Seite

              Hallo Raketenwilli,

              • Zeig mal wie Du Deine Klassen lädst. Also (wohl) den Autoloader.

              wie meinst du das? require '../vendor/autoload.php';, oder wie? Oder wie die Router-Klasse die Controller-Klassen ermittelt?

              • Strato? Da war doch was mit ungewöhnlichen Links bzw. Mounts. Möglicherweise muss irgendwo ein realpath($verzeichnis) hin.

              Hmm … das werde ich mal recherchieren.

              1. problematische Seite

                Hallo Raketenwilli,

                • Zeig mal wie Du Deine Klassen lädst. Also (wohl) den Autoloader.

                wie meinst du das? require '../vendor/autoload.php';, oder wie? Oder wie die Router-Klasse die Controller-Klassen ermittelt?

                • Strato? Da war doch was mit ungewöhnlichen Links bzw. Mounts. Möglicherweise muss irgendwo ein realpath($verzeichnis) hin.

                Hmm … das werde ich mal recherchieren.

                Hm. Und dann die autoload.php und dann die Namenspaces, welche diese adressiert.

                1. problematische Seite

                  Hm. Und dann die autoload.php und dann die Namenspaces, welche diese adressiert.

                  {
                      "name": "borisbaer/framework",
                  	"autoload": {
                  		"psr-4": {
                  			 "App\\": "app/",
                  			 "Core\\": "core/"
                  		}
                  	},
                      "authors": [
                          {
                              "name": "Boris Bär"
                          }
                      ],
                      "require": {
                          "vlucas/phpdotenv": "^5.4"
                      }
                  }
                  

                  Ich bin mir nicht ganz sicher, ob du das hier meinst. Ich habe das Ding einfach mit dem Composer installiert. Das befindet sich in der Datei composer.json, in vendor/autoload.php stehen keine interessanten Informationen oder irgendwas mit Namespaces. Aber es könnte sein, dass du hier dem Problem auf der Spur bist. Meine Dateien und Ordner sind halt durchweg kleingeschrieben normalerweise, auch wenn viele das bei einem PHP-MVC-Framework anders machen.

                  Nachtrag: Es lag wirklich daran! Die Autoload-Verweise für Core\ und App\ sind kleingeschrieben und daher musste ich das bei der Pfadbeschreibung auch berücksichtigen. War also tatsächlich ein Problem mit der case sensitivity.

                  ABER ... warum zum Geier wird bei mir der Inhalt über dem Header angezeigt? Das ist auf meinem lokalen Server auch nicht so.

                  1. problematische Seite

                    ABER ... warum zum Geier wird bei mir der Inhalt über dem Header angezeigt? Das ist auf meinem lokalen Server auch nicht so.

                    Scheinbar benutzt Du ja das Output-Buffering. Da dieses bei Strato womöglich aus ist solltest Du das mit ini_get( 'output_buffering' ) kontrollieren und ggf. selbst setzen (ist veränderbar: „PHP_INI_PERDIR“) oder mal versuchen, ob ein rechtzeitiges ob_start() Deine Probleme löst.

                    Und schau nach, ob der Buffer groß genug ist…

                    1. problematische Seite

                      Scheinbar benutzt Du ja das Output-Buffering. Da dieses bei Strato womöglich aus ist solltest Du das mit ini_get( 'output_buffering' ) kontrollieren und ggf. selbst setzen (ist veränderbar: „PHP_INI_PERDIR“) oder mal versuchen, ob ein rechtzeitiges ob_start() Deine Probleme löst.

                      Und schau nach, ob der Buffer groß genug ist…

                      Danke für die Hinweise! Sorry, ich hatte unter Martins Beitrag bereits geschrieben, dass es am ob_start() lag. Aber vielen Dank für die Hilfe, es funktioniert jetzt alles! 👍

          2. problematische Seite

            Hallo,

            austauschen?

            Das habe ich getan, und jetzt wird zumindest diese Fehlermeldung nicht mehr angezeigt und das Seiten-Layout wird ganz normal gerendert. Danke!

            klar, weil $view dann zum String "bool: false" aufgelöst wird, und der passt in dein syntaktisches Schema. Damit kurierst du aber nur Symptome, nicht die Ursachen.

            Ich verstehe aber trotzdem nicht, was hier eigentlich das Problem war. Auf dem STRATO-Server ist’s ein bool, lokal ist’s ein string. Das kann doch irgendwie nicht sein. 😵

            Genau, hier solltest du mit deinen Recherchen ansetzen.

            Einen schönen Tag noch
             Martin

            --
            Wer nicht genießt, wird ungenießbar.
            (Mottospruch auf einem T-Shirt)
            1. problematische Seite

              Hallo Martin,

              Genau, hier solltest du mit deinen Recherchen ansetzen.

              nun, ich weiß zwar immer noch nicht, warum genau der Server das so interpretiert, aber eine Lösung konnte ich nun finden: Ein weiteres ob_start(); vor dem zweiten include-Befehl hat diese Fehlermeldung beseitigt, ohne dass ich $view als string erzwingen musste.

              Auch das Problem mit dem falsch gesetzten Main-Tag hat sich dadurch erübrigt. Schön! Mir bleibt nur weiterhin schleierhaft, warum der Online-Server es anders handhabt als der Offline-Server …

              Jetzt scheint aber alles soweit zu funktionieren. 🙂

              1. problematische Seite

                Mir bleibt nur weiterhin schleierhaft, warum der Online-Server es anders handhabt als der Offline-Server …

                XAMPP trifft etliche Voreinstellungen, die nicht denen entsprechen, mit denen die Programme (Apache, MySQL, PHP) sonst ausgeliefert werden.

                Anderes liegt eben an Windows selbst: In der PHP-Doc wird an so einigen Stellen beschrieben, was unter Windows nicht geht. Liegt teils am Dateisystem, teils am Netzwerk-Stack, teilweise an der Unvollständigkeit der C-Lib für Windows oder so… Es gibt aber auch „NUR-Windows-Funktionalitäten“. Ich vermute nur nicht, dass Du darauf gestoßen bist.

                Und die Sache mit der GROSS/klein-Schreibung? Das liegt schlicht daran, dass Microsoft da seit MS-DOS und Window 95 großen Mist mit sich rumschleppt und zur PRÄ-ASCII-Vergangenheit kompatibel bleiben will - damit manche Benutzer oder „Programmierer“ nicht weinen.

                1. problematische Seite

                  Mir bleibt nur weiterhin schleierhaft, warum der Online-Server es anders handhabt als der Offline-Server …

                  XAMPP trifft etliche Voreinstellungen, die nicht denen entsprechen, mit denen die Programme (Apache, MySQL, PHP) sonst ausgeliefert werden.

                  Anderes liegt eben an Windows selbst: In der PHP-Doc wird an so einigen Stellen beschrieben, was unter Windows nicht geht. Liegt teils am Dateisystem, teils am Netzwerk-Stack, teilweise an der Unvollständigkeit der C-Lib für Windows oder so… Es gibt aber auch „NUR-Windows-Funktionalitäten“. Ich vermute nur nicht, dass Du darauf gestoßen bist.

                  Und die Sache mit der GROSS/klein-Schreibung? Das liegt schlicht daran, dass Microsoft da seit MS-DOS und Window 95 großen Mist mit sich rumschleppt und zur PRÄ-ASCII-Vergangenheit kompatibel bleiben will - damit manche Benutzer oder „Programmierer“ nicht weinen.

                  Noch ein Grund:

                  Soweit ich das noch weiß lädt XAMPP PHP als Modul des Apache - genau so wie es auch auf „Allerwelts-Testinstallationen“ der Linux-Distributionen installiert wird. Aber auf echten Servern hast Du regelmäßig PHP als „sonstwas-cgi“ (hier seit einigen Tagen „fpm-cgi“ wegen HTTP2) laufen. Und tatsächlich gibt es dann Dinge die PHP eben nur als Modul kann. Dies weil diese Funktionalitäten z.B. voraussetzen, das PHP (als Modul des Apache-Webservers) mit diesem zusammen quasi durchläuft. Nur zum Beispiel: Das Aufrechterhalten und die Weiterverwendung der Datenbankverbindung (konkreter: der aufgebauten TCP-Verbindung) über das Skript(sic!)ende hinaus.

                  Ein Blick nach /etc/php/x.y/zeigt Dir, dass es schon systemweit mehrere PHP-Inis gibt. Ich habe hier:

                  /etc/php/8.2
                            + /cgi
                            + /cli
                            + /embed
                            + /fpm