treziman: session-lifetime in php.ini

Hallo,

es geht um folgendes:
Ich habe bei meinem Provider die Möglichkeit, eine eigene php.ini zu erstellen. Mit den jetzigen Einstellungen bin ich zufrieden, bis auf die Laufzeit der sessions. Die sind mir zu kurz (1440), da ein User z.B. viel Text lesen kann, und da sind 24 min schnell weg.

Ich möchte die Laufzeit auf 2 Stunden einstellen, etwa so:

In der php.ini:

session.gc_maxlifetime(7200);

Nun meine Fragen, auf die ich bisher keine Antworten gefunden habe.

Reicht in der php.ini dieser eine Eintrag? Und "weiss" php aus welcher ini-datei es die Einstellungen nehmen soll?

Nach meinem Wissen müsste es jetzt so aussehen: php nimmt die session-lifetime aus meiner php.ini und alle anderen Einstellungen aus der serverseitigen php.ini ?

Gruss
Thorsten

  1. Hallo Thorsten,

    meines wissens verarbeitet PHP standartmäßig nur eine php.ini und das ist natrülich die Serverseitige. Den Pfad/Ort finden und deren Einstellungen überprüfen kannst du per phpinfo().

    In der php.ini solltest du ersteinmal suchen ob der Wert session.gc_maxlifetime schon gesetzt wurde. Wenn ja einfach nur verändern, wenn nein, deine Zeile unten in die php.ini kopieren.

    Ich hoffe das hilft!

    Gruß Zeddix

    1. Hallo Thorsten,

      meines wissens verarbeitet PHP standartmäßig nur eine php.ini und das ist natrülich die Serverseitige. Den Pfad/Ort finden und deren Einstellungen überprüfen kannst du per phpinfo().

      In der php.ini solltest du ersteinmal suchen ob der Wert session.gc_maxlifetime schon gesetzt wurde. Wenn ja einfach nur verändern, wenn nein, deine Zeile unten in die php.ini kopieren.

      Ich hoffe das hilft!

      Gruß Zeddix

      Hallo Thorsten,

      Zeddix hat absolut Recht, PHP verwendet nur eine php.ini.
      Solltest Du die vom Provider vorgegebene ini-Datei weiter verwenden wollen und nur den Timeout ändern kannst Du das aber auch während der Laufzeit Deiner Scripte tun.
      Sollte eigentlich in etwa so gehen:

        
      ini_set('session.gc_maxlifetime', 3600);  
      ini_set('session.gc_divisor', 1);  
      session_start();  
      
      

      Damit wird die php.ini immernoch vom Provider geladen, der Einstellungswert aber nachträglich überschrieben.
      Aber Vorsicht: Wenn Du nicht alles über eine zentrale index.php laufen lässt muss das in jeder Datei die aufgerufen wird stehen.

      mfg
      Flanna

      1. Hallo,

        und hallo dedlfix. Ich freue mich, dass wir uns hier "wiedersehen". Das Prob mit der DB ist gelöst.

        (code lang=php) (Anmerkung: eckige Klammern werden wohl nicht angezeigt)
        ini_set('session.gc_maxlifetime', 3600);
        ini_set('session.gc_divisor', 1);
        session_start();
        (/code)

        Dieser code-Schnipsel zu Beginn eines jeden scripts wäre nicht schlimm. Würde ich eh mit include machen (+ falls erforderlich Verbindung mit DB).
        Hauptsache es funktioniert.

        Ich habe mal die phpinfo() laufen lassen.
        session.gc_divisor ist 1000
        session.gc_maxlifetime ist 1440

        Also würde mein script wie folgt aussehen:

        <?php
        mysql_connect("localhost","root") or die ("Keine Verbindung");
        ini_set('session.gc_maxlifetime', 7200);
        ini_set('session.gc_divisor', 1);
        session_start();
        ...
        ?>

        Wäre das korrekt?

        Gruss
        Thorsten

        1. So sollte es funktionieren ja. Wobei die Divisor-Einstellung eigentlich nicht von interesse ist. Die hab ich nur versehentlich mitkopiert.
          Divisor gibt zusammen mit gc_probability eigentlich nur an wie hoch die Wahrscheinlichkeit ist das der Garbage-Collector gestartet wird der dann die abgelaufenen Sessions aufräumt.

          Insofern müsste:

            
          <?php  
          mysql_connect("localhost","root") or die ("Keine Verbindung");  
          ini_set('session.gc_maxlifetime', 7200);  
          session_start();  
          ...  
          ?>
          

          eigentlich ausreichen.

          Sollten noch Probleme entstehen kann php.net helfen:
          Laufzeitkonfiguration von Seessions

          Kleiner Tip noch am Rande: Es ist nicht unbedingt empfehlenswert den Root-User für Datenbank-Zugriffe von Webseiten aus zu nutzen. Besonders wenn mehrere Datenbanken auf dem MySql-Server laufen hat der root-User auf alle Zugriff.
          In der Praxis bedeutet das, sollte jemand einen Angriffsvektor für eine SQL-Injection finden, kann er Dir sämtliche Datenbanken Platt machen.

          Natürlich sollte im normalfall garkeine SQL-Injection möglich sein. Aber lieber vorbeugen als sich auf die Füsse kotz** ;)

          1. Hi!

            So sollte es funktionieren ja.

            Jein. Das Ändern der Zeiten allein reicht nicht, wenn kein separater session.save_path verwendet wird, sonst räumen anders initialisierte GCs die Session trotzdem weg. Wenn man das nicht beachtet, hat die schwer nachvollziehbaren Effekte, dass Sessions manchmal vorzeitig ablaufen.

            mysql_connect("localhost","root") or die ("Keine Verbindung");
            Kleiner Tip noch am Rande: Es ist nicht unbedingt empfehlenswert den Root-User für Datenbank-Zugriffe von Webseiten aus zu nutzen. Besonders wenn mehrere Datenbanken auf dem MySql-Server laufen hat der root-User auf alle Zugriff.

            Auch ist or die() keine zu empfehlende Fehler"behandlung". Die Ausgabe erfolgt an den Anwender, der damit weder was anfangen kann noch soll, besonders wenn die Ausgabe noch mit dem mysql_error()-Text versehen wird.

            In der Praxis bedeutet das, sollte jemand einen Angriffsvektor für eine SQL-Injection finden, kann er Dir sämtliche Datenbanken Platt machen.

            Jein. Solche Maximalschäden sind mit SQL-Injection üblicherweise und unter MySQL nicht möglich. Die Stellen an denen SQL-Injection greift sind meist nach der einleitenden Statement-Klausel (SELECT ..., DELETE ..., etc.) eingebaut, so dass das Statement maximal ergänzt und erweitert werden kann. Ein Anhängen von ;DROP... erfordert, dass der PHP-Programmierer mysqli_multi_query() verwendet hat.

            Natürlich sollte im normalfall garkeine SQL-Injection möglich sein. Aber lieber vorbeugen als sich auf die Füsse kotz** ;)

            Es geht dabei auch eher um Lücken, die der Anwendungsprogrammierer üblicherweise nicht direkt beeinflussen kann, weil sie im MySQL-Server selbst enthalten sind. Um Statements zu erweitern, reicht eine eingeschränkte Kennung, weil man mit der ja sowieso das eigentlich vorgesehene Statement abarbeiten können muss.

            Lo!

            1. Jein. Das Ändern der Zeiten allein reicht nicht, wenn kein separater session.save_path verwendet wird, sonst räumen anders initialisierte GCs die Session trotzdem weg. Wenn man das nicht beachtet, hat die schwer nachvollziehbaren Effekte, dass Sessions manchmal vorzeitig ablaufen.

              Ich glaube, genau dieses Problem hatte ich vor ca. 1 1/2 Jahren, als ich mit php anfing und die session-lifetime verändern wollte, was eben nicht klappte. Damals habe ich dieses Problem dadurch umgangen, dass ich eben eine eindeutige user-id von script zu script per input-hidden oder an links angehängt weitergab. So konnte ich abgelaufene sessions immer wieder herstellen (darauf zielte auch mein posting unter 'Datenbank').
              Diese Lösung kann ich jetzt aber nicht nehmen, da der Inhalt der weiterzugebenden Variable einerseits bei links am unteren Browserfenster, andererseits nach Ausführung des scripts beim Anzeigen des Quellcodes, sichtbar wird. Beides soll nicht sein.

              Es muss also ein anderer Pfad als der defaultmässige angegeben werden? Etwa:

              <?php
              ini_set ( session.save_path, "domain\SessionTemp" );
              ini_set ( session.gc_maxlifetime (7200));
              session_start ();
              ...
              ?>

              Auf die MySql-DB komme ich nochmal zurück. Nur soviel, es wird nur eine DB geben, aber mit mehreren Tabellen.

              Gruss
              Thorsten

              1. Hi!

                Es muss also ein anderer Pfad als der defaultmässige angegeben werden? Etwa:
                ini_set ( session.save_path, "domain\SessionTemp" );

                Im Prinzip ja, wenn das nicht bereits der Hoster schon berücksichtigt hat. Und es ist sehr zu empfehlen, dass der Pfad außerhalb des DocumentRoot zu liegen kommt. Dazu muss man gegebenenfalls erst einmal Voraussetzungen schaffen, wenn das Kundenverzeichnis gleich DocumentRoot für mindestens eine Domain ist. Am besten ist, für jedes Projekt ein Unterverzeichnis anzulegen und die Domains/DocumentRoot darauf verweisen zu lassen. Neben diesen Unterverzeichnissen hat man dann noch Platz für das Zeug, das nicht öffentlich sein soll, wie Session-Dateien, Konfigurationsdateien, Dateien mit Zugriffkontrolle über Scripts, und so weiter.

                Lo!

                1. Ein umsetzen von session.name sollte ausreichen damit der "fremde" gc nichtmehr die eigenen Sessions wegräumt.
                  Im Gegensatz zum save-path ändern bleiben die session-Dateien damit weg aus Deinem Webspace. Ist bei entsprechender Grösse des Webspace oder wenig erwarteten Sessions natürlich relativ egal.
                  Ist der Webspace hingegen eher eng und es sind viele Sessions zu erwarten (+Du speicherst viele Daten in der Seesion ab), dann treibt Dir das den benötigten Speicherplatz hoch. Worst-Case: Was passiert wohl wenn Dein Quota voll ist und PHP ne neue Session anlegen will? :D

                2. Und es ist sehr zu empfehlen, dass der Pfad außerhalb des DocumentRoot zu liegen kommt. Dazu muss man gegebenenfalls erst einmal Voraussetzungen schaffen, wenn das Kundenverzeichnis gleich DocumentRoot für mindestens eine Domain ist. Am besten ist, für jedes Projekt ein Unterverzeichnis anzulegen und die Domains/DocumentRoot darauf verweisen zu lassen. Neben diesen Unterverzeichnissen hat man dann noch Platz für das Zeug, das nicht öffentlich sein soll, wie Session-Dateien, Konfigurationsdateien, Dateien mit Zugriffkontrolle über Scripts, und so weiter.

                  Das verstehe ich jetzt nicht wirklich. Ich kann ja nur einen Pfad innerhalb meiner Domain auf dem Server meines Providers angeben.
                  A la:
                  domain/scripts
                  domain/tmp/sessions
                  domain/userdata

                  oder so ähnlich.

                  Ich schaue mich aber nochmal bei meinem Provider um (kann mich da grad wieder mal nicht einloggen...!).

                  Gruss
                  Thorsten

                  1. Hi!

                    Und es ist sehr zu empfehlen, dass der Pfad außerhalb des DocumentRoot zu liegen kommt. Dazu muss man gegebenenfalls erst einmal Voraussetzungen schaffen, wenn das Kundenverzeichnis gleich DocumentRoot für mindestens eine Domain ist. Am besten ist, für jedes Projekt ein Unterverzeichnis anzulegen und die Domains/DocumentRoot darauf verweisen zu lassen. Neben diesen Unterverzeichnissen hat man dann noch Platz für das Zeug, das nicht öffentlich sein soll, wie Session-Dateien, Konfigurationsdateien, Dateien mit Zugriffkontrolle über Scripts, und so weiter.
                    Das verstehe ich jetzt nicht wirklich. Ich kann ja nur einen Pfad innerhalb meiner Domain auf dem Server meines Providers angeben.
                    A la:
                    domain/scripts
                    domain/tmp/sessions
                    domain/userdata
                    oder so ähnlich.

                    Wenn ein Hoster die Möglichkeit anbietet, dass man mehrere Domains bekommen kann, so ist es sehr sinnvoll, dass man pro Domain ein eigenes Unterverzeichnis erstellen kann, sonst kann man von der Hauptdomain auf alle anderen Domains durchgreifen, wenn man deren Pfad kennt.

                    /kunden/x/ <- DocumentRoot für example.com
                      /kunden/x/org <- DocumentRoot für example.org

                    Damit kommt man mit example.com/org ebenfalls auf die org-Inhalte, was meist nicht gewünscht ist. Man muss das also so aufsetzen können:

                    /kunden/x/com <- DocumentRoot für example.com
                      /kunden/x/org <- DocumentRoot für example.org

                    Und dann hat man Platz für

                    /kunden/x/privates

                    Ein guter Hoster richtet das gleich so ein:

                    /kunden/x/domain1/www  <- DocomentRoot
                      /kunden/x/domain1/configdata
                      /kunden/x/domain1/privates

                    und für alle weiteren Domains ebenso. Dies ist auf alle Fälle bei 1&1 so konfigurierbar, obwohl man im Auslieferungszustand das bekommt:

                    /kunden/x/ <- DocumentRoot für die inklusive sMitZahlenkolonne.online.de und die erste Domain, wenn die beim Bestellen mitbestellt wurde.

                    Man muss nun nur ein Unterverzeichnis anlegen und bei der Domainkonfiguration unter Verwendungsart ein anderes Verzeichnis einstellen, so dass man erhält:

                    /kunden/x/nixdrin <- sMitZahlenkolonne.online.de
                      /kunden/x/domain1 <- erste Domain

                    Lo!

                    1. Hallo,

                      jetzt sehe ich klarer. Ich glaube aber, damit muss ich mich nicht unbedingt beschäftigen, weil ich nur eine Domain habe. Zwar noch eine Subdomain, die ich aber nicht brauche. Beide zeigen tatsächlich auf dieselbe index.html.

                      Für meine Zwecke müsste dann reichen, wenn ich einen Pfad angebe:

                      domain/tmp (vorher natürlich angelegt)

                      und da hinein die sessions speichere?

                      Gruss
                      Thorsten

                      1. Hi!

                        jetzt sehe ich klarer. Ich glaube aber, damit muss ich mich nicht unbedingt beschäftigen, weil ich nur eine Domain habe. Zwar noch eine Subdomain, die ich aber nicht brauche. Beide zeigen tatsächlich auf dieselbe index.html.

                        Genauer gesagt: Sie zeigen nicht auf die index.html sondern auf ein DocumentRoot. Das ist ein Verzeichnis, dessen DefaultDocument die index.html ist.

                        Für meine Zwecke müsste dann reichen, wenn ich einen Pfad angebe:
                        domain/tmp (vorher natürlich angelegt)
                        und da hinein die sessions speichere?

                        Und damit hast du das tmp-Verzeichnis innerhalb des DocumentRoot, was bedeutet, dass man Requests darauf absetzen kann. Man kann zwar eine Auslieferung von Dateien aus diesem Verzeichnis zu verhindern versuchen, indem man eine Zugriffbeschränkung darauf konfiguriert, doch muss man nun dafür Sorge tragen, dass die dazu üblicherweise eingesetzte .htaccess unter keinen Umständen gelöscht wird. Das von mir erläuterte Prinzip kann man auch mit einer einzigen Domain umsetzen. Und man muss es sogar, wenn man Platz für Verzeichnisse außerhalb des DocumentRoot haben will.

                        Lo!

                        1. Ich habe mich jetzt genau bei meinem Provider umgesehen. Es sieht wohl so aus, dass ich keinen Pfad ausserhalb meiner Domain anlegen kann. Ich kann zwar die Domain auf ein Unterverzeichnis verweisen, was mir aber nichts nützt.
                          Ich habe auch keine Option gefunden, um derartige Einstellungen vorzunehmen. Soetwas müsste unter "Grundeinstellungen" oder "Profianwendungen" zu finden sein. Nichts.

                          Ich lande, starte ich den Homepagebereich, im Hauptmenü. Von da aus lande ich unter "filemanager" gleich im Hauptverzeichnis der Domain.

                          Als ich mal ein kleineres Projekt für einen Freund programmiert habe, wobei dieser sich um den Hoster gekümmert hat, auf den ich dann Zugriff bekam, da kam man unter "filemanager" zunächst auf ein Menü mit mehreren Ordnern. Der Ordner "html" beinhaltete schliesslich die index.html und alle anderen scripte. Soweit ich mich erinnere, gab es auch Ordner wie "PHP", "tmp" und "admin". Ist bei mir aber leider so nicht gestaltet.

                          Gruss
                          Thorsten

                          1. Hi!

                            Ich habe mich jetzt genau bei meinem Provider umgesehen. Es sieht wohl so aus, dass ich keinen Pfad ausserhalb meiner Domain anlegen kann.

                            Ich nehme an, dass du kein Verzeichnis außerhalb deines Kundenverzeichnisses anlegen kannst. Dein Kundenverzeichnis ist sozusagen dein Wurzelverzeichnis. Natürlich kann das DocumentRoot auch das Wurzelverzeichnis sein, aber es kann auch ein Unterverzeichnis sein.

                            Ich kann zwar die Domain auf ein Unterverzeichnis verweisen, was mir aber nichts nützt.

                            Doch, genau das ist es, was du machen musst: Ein Unterverzeichnis in deinem Kunden-/Wurzelverzeichnis anlegen und die Domain darauf zeigen lassen.

                            Als ich mal ein kleineres Projekt für einen Freund programmiert habe, wobei dieser sich um den Hoster gekümmert hat, auf den ich dann Zugriff bekam, da kam man unter "filemanager" zunächst auf ein Menü mit mehreren Ordnern. Der Ordner "html" beinhaltete schliesslich die index.html und alle anderen scripte.

                            Damit ist das Verzeichnis html das DocumentRoot. Oder wie du es nennst Domainverzeichnis.

                            Soweit ich mich erinnere, gab es auch Ordner wie "PHP", "tmp" und "admin". Ist bei mir aber leider so nicht gestaltet.

                            Sollte aber nach deiner Aussage, die Domain auf ein Unterverzeichnis verweisen lassen zu können, ohne weiteres auch machbar sein.

                            Lo!

                            1. Das würde dann bei mir so z.B. aussehen:

                              "domain/html" (beinhaltet die scripte; domain hierhin verweisen)

                              "domain/sessiontmp" (den sessionpath hierhin verweisen)

                              Gruss
                              Thorsten

                              1. Hi!

                                Das würde dann bei mir so z.B. aussehen:
                                "domain/html" (beinhaltet die scripte; domain hierhin verweisen)
                                "domain/sessiontmp" (den sessionpath hierhin verweisen)

                                Beispielsweise ja. So hast du ein exklusives DocumentRoot für die Domain, Platz daneben und auch noch welchen für weitere Domains mit eigenständigen Verzeichnissen.

                                Lo!

    2. Hi!

      meines wissens verarbeitet PHP standartmäßig nur eine php.ini und das ist natrülich die Serverseitige.

      Erstens heißt es immer noch Standard mit d am Ende, und zweitens ist eine php.ini immer serverseitig. Was soll sie auch sonst sein? Es gibt aber Feinheiten, welche php.ini verwendet wird. Bei PHP als Modul wird eine php.ini nur einmalig beim Start des Webservers eingelesen. Individuelle Einstellungen können dann nur über die Apache-Konfiguration geändert werden. Bei CGI wird PHP mit jedem Scriptaufruf neu gestartet, und liest dabei auch die php.ini neu ein. Und dabei gibt es die Möglichkeit, eine eigene php.ini wirksam werden zu lassen. Diese bietet anscheinend der Hoster des OP und ich weiß, dass diese Möglichkeit bei 1&1 genutzt werden kann.

      Den Pfad/Ort finden und deren Einstellungen überprüfen kannst du per phpinfo().

      Ja, das ist der Ort der aktuellen php.ini, der aber nicht in Stein gemeißelt ist. Bei einer wirksam selbst hinzugefügten php.ini wird phpinfo() diese anzeigen.

      Lo!

  2. Hi!

    Ich möchte die Laufzeit auf 2 Stunden einstellen, etwa so:
    In der php.ini:
    session.gc_maxlifetime(7200);

    Das ini-Format ist anders, nämlich mit = zwischen Direktivennamen und Wert, ohne Klammern und ohne abschließendes Zeichen (beziehungsweise Zeilenumbruch reicht).

    Reicht in der php.ini dieser eine Eintrag?

    Jein. Es ist auch noch erforderlich, dass session.save_path auf ein individuelles Verzeichnis verweist. Der Session-Garbage-Collector räumt nämlich nach seinen individuellen Vorgaben sämtliche Session-Dateien auf, weil er keinen Unterschied zwischen den Projektzugehörigkeiten macht oder vielmehr machen kann, denn es gibt kein Merkmal, das eine Zugehörigkeit von Sessions zu Projekten kennzeichnet.

    Und "weiss" php aus welcher ini-datei es die Einstellungen nehmen soll?

    Das ist eine Frage der Grundkonfiguration PHPs, die mitunter schon beim Kompilieren bestimmt wird. Es gibt Konstellationen, besonders wenn PHP als CGI betrieben wird, da kann eine php.ini im Verzeichnis der aufgerufenen Datei die serverseitige außer Kraft setzen.

    Nach meinem Wissen müsste es jetzt so aussehen: php nimmt die session-lifetime aus meiner php.ini und alle anderen Einstellungen aus der serverseitigen php.ini ?

    Nein, dieses Verhalten bietet nur die .user.ini (ab PHP 5.3). Eine eigene php.ini bedeutet, dass sämtliche Einstellungen aus dieser genommen werden. Das bedeutet wiederum, dass du spezielle Einstellungen des Hosters händisch übernehmen musst. Besonders solche Werte wie mysql(i).default_socket können wichtig sein, wenn der Hoster einen Zugriff über Socket statt TCP haben will. Alle sicherheitsrelevanten Werte sollten - eine aktuelle PHP-Version vorausgesetzt - nach aktuellen Default-Vorgaben eingestellt sein, wenn der Hoster nichts anderes einkompiliert hat. Hier schadet eine Überprüfung nicht.

    Lo!