Eddie: Datei cachen - ist dieses Verfahren technisch machbar?

Hallo allerseits,

ich moechte ein paar Grafiken, die eigentlich dynamisch erzeugt werden, auf der Festplatte "vorratsspeichern".

Der normale Ablauf wäre ja, soweit ich weiss, folgender:
das zuständige Skript (bspw. grafik.php) wird aufgerufen und schaut, ob die Grafik bereits existiert. Existiert sie, wird sie eben ausgeliefert. Existiert sie nicht, wird sie erzeugt, gespeichert und dann ausgeliefert.

Jetzt würde ich den Existenzcheck gerne zuerst machen!!! Also: die Grafik im Cache wird direkt verlinkt. Das würde meinen PHP-Parser entlasten, was mir nur Recht wäre!

Problem: was passiert, wenn die Grafik noch nicht existiert? Kann ich es so einrichten, dass der Server (Apache) die Anfrage erst dann auf mein Skript umleitet, und zwar so, dass der User und auch dessen Browser nichts davon mitkriegen?

Danke für eure Hilfe,
Eddie

--
Old men and far travelers may lie with authority.
  1. Hi,

    Der normale Ablauf wäre ja, soweit ich weiss, folgender:
    das zuständige Skript (bspw. grafik.php) wird aufgerufen und schaut, ob die Grafik bereits existiert. Existiert sie, wird sie eben ausgeliefert. Existiert sie nicht, wird sie erzeugt, gespeichert und dann ausgeliefert.

    Jetzt würde ich den Existenzcheck gerne zuerst machen!!! Also: die Grafik im Cache wird direkt verlinkt. Das würde meinen PHP-Parser entlasten, was mir nur Recht wäre!

    Richte Dein PHP-Script als error-Document für 404 not found für das Verzeichnis mit den Grafiken ein.

    Sorg dann dafür, daß es nach erfolgreichem Erzeugen der Graphik diese mit passendem Status (200 ok) ausliefert.

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    Schreinerei Waechter
    O o ostern ...
    Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
    1. Hallo nochmal,

      Richte Dein PHP-Script als error-Document für 404 not found für das Verzeichnis mit den Grafiken ein.

      Sorg dann dafür, daß es nach erfolgreichem Erzeugen der Graphik diese mit passendem Status (200 ok) ausliefert.

      Danke dir Andreas, das klingt doch schonmal garnicht so kompliziert, wie ich mir das gedacht habe :-)

      Jetzt habe ich aber doch noch eine etwas allgemeinere Frage, weil ich mich gerade wundere, ob ich das Konzept des Cachings nicht etwas unterschaetze. Für mich klingt das bisher alles recht einfach:

      1. jede neue Grafik kommt ins Verzeichnis /cache/
      2. bei jedem Aufruf bekommt die entsprechende Datei ein neues Zugriffsdatum verpasst
      3. in regelmäßigen Abständen lasse ich einen Cronjob laufen, der dann abhängig vom Zugriffsdatum aufräumt

      Das klingt ja alles sehr einfach. Übersehe ich da was? Gibt es bspw. zusätzliche Mechanismen, die ich vorsehen sollte, falls richtig viele (>100.000) Dateien zusammenkommen?

      Ihr seht, ich mach das grad zum ersten Mal :-)

      Eddie

      --
      Old men and far travelers may lie with authority.
      1. Hi,

        Jetzt habe ich aber doch noch eine etwas allgemeinere Frage, weil ich mich gerade wundere, ob ich das Konzept des Cachings nicht etwas unterschaetze. Für mich klingt das bisher alles recht einfach:

        1. jede neue Grafik kommt ins Verzeichnis /cache/
        2. bei jedem Aufruf bekommt die entsprechende Datei ein neues Zugriffsdatum verpasst
        3. in regelmäßigen Abständen lasse ich einen Cronjob laufen, der dann abhängig vom Zugriffsdatum aufräumt

        Ggf. das Löschen von alten Dateien nicht per Cronjob, sondern vom graphik-erzeugenden Script mit erledigen lassen:
        Wenn das Script feststellt, daß mehr als n Graphiken existieren, lösche die ältesten.

        cu,
        Andreas

        --
        Warum nennt sich Andreas hier MudGuard?
        Schreinerei Waechter
        O o ostern ...
        Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
        1. Hello,

          Ggf. das Löschen von alten Dateien nicht per Cronjob, sondern vom graphik-erzeugenden Script mit erledigen lassen:
          Wenn das Script feststellt, daß mehr als n Graphiken existieren, lösche die ältesten.

          Das wird aber, wenn ich Edii richtig verstanden habe, vom User angestoßen. Und der müsste dann solange warten....................................................

          Das ist nicht so günstig.

          Harzliche Grüße vom Berg
          http://www.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau

          1. Hi,

            Ggf. das Löschen von alten Dateien nicht per Cronjob, sondern vom graphik-erzeugenden Script mit erledigen lassen:
            Wenn das Script feststellt, daß mehr als n Graphiken existieren, lösche die ältesten.

            Das wird aber, wenn ich Edii richtig verstanden habe, vom User angestoßen. Und der müsste dann solange warten....................................................

            1. kann man ja auch erst die neue Graphik erstellen und ausliefern und dann die Dateien löschen

            2. sooo ewig dauert das Löschen von einer Handvoll Graphiken ja auch nicht (viel mehr können es ja eigentlich nicht werden, da ja bei Überschreiten der Anzahl gleich gelöscht wird).

            cu,
            Andreas

            --
            Warum nennt sich Andreas hier MudGuard?
            Schreinerei Waechter
            O o ostern ...
            Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
            1. Hello,

              Das wird aber, wenn ich Edii richtig verstanden habe, vom User angestoßen. Und der müsste dann solange warten....................................................

              1. kann man ja auch erst die neue Graphik erstellen und ausliefern und dann die Dateien löschen

              Nö, denn das Script läuft dann trotzdem solange bis zum ConnectionClose() und der User muss warten.

              1. sooo ewig dauert das Löschen von einer Handvoll Graphiken ja auch nicht (viel mehr können es ja eigentlich nicht werden, da ja bei Überschreiten der Anzahl gleich gelöscht wird).

              Man könnte das Löschscript aber abspalten oder am besten gelich einen Systembefehl benutzen mittels exec().

              Harzliche Grüße vom Berg
              http://www.annerschbarrich.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              Nur selber lernen macht schlau

              1. hi,

                1. kann man ja auch erst die neue Graphik erstellen und ausliefern und dann die Dateien löschen

                Nö, denn das Script läuft dann trotzdem solange bis zum ConnectionClose() und der User muss warten.

                flush() existiert ja.
                Und ob die Verbindung nach dem Empfangen des Bildes noch ein weniggehalten wird, weil das Script im Hintergrund noch etwas anderes macht, dürfte den User nicht sonderlich stören.

                gruß,
                wahsaga

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

                  flush() existiert ja.
                  Und ob die Verbindung nach dem Empfangen des Bildes noch ein weniggehalten wird, weil das Script im Hintergrund noch etwas anderes macht, dürfte den User nicht sonderlich stören.

                  Das hängt vom Browser ab.
                  Er kann wahrscheinlich nichts anders machen, als zu warten, oder aber den Cancel-Button zu drücken.

                  Harzliche Grüße vom Berg
                  http://www.annerschbarrich.de

                  Tom

                  --
                  Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                  Nur selber lernen macht schlau

                  1. Hallo allerseits,

                    danke euch fuer eure rege Beteiligung, das hilft mir sehr!

                    Ich denke, in meinem Fall wird ein stuendlicher Cronjob genuegen, der im Hintergrund ablaeuft. Im Grunde werde ich zwei Sorten Dateien haben, naemlich "Testversionen" (die zustande kommen, wenn der User rumexperimentiert) und endgültige Versionen.
                    Die Testversionen werden eine kurze Haltbarkeit haben (bspw. eine Stunde oder sogar nur 5 Minuten), abhaengig von ihrem ERSTELLUNGSDATUM.
                    Die endgültigen Versionen haben dann eine laenger Haltbarkeit (bspw. 24 Stunden), aber abhaengig von ihrem LETZTEN ZUGRIFFSDATUM. Werden sie also regelmaessig verwendet, kann ihre Haltbarkeit durchaus der Projektlaufzeit entsprechen.

                    Eddie

                    --
                    Old men and far travelers may lie with authority.
      2. Moin!

        Das klingt ja alles sehr einfach. Übersehe ich da was? Gibt es bspw. zusätzliche Mechanismen, die ich vorsehen sollte, falls richtig viele (>100.000) Dateien zusammenkommen?

        Wenn du sehr viele Dateien voraussiehst, solltest du die nicht alle in ein einziges Verzeichnis packen, sondern mehrere Verzeichnisse dafür vorsehen.

        Typische Applikationen, die unbekannt viele Dateien erzeugen könnten, und deren Dateinamen z.B. Hexzahlen sind, erzeugen meist folgende Struktur:

        Dateiname beginnt mit 0FE3....
        Datei liegt in /prefix/0/F/E/3/0FE3....

        Das kann man in vier Stufen machen, wie im Beispiel, oder auch in weniger oder mehr (sofern das Szenario wirklich von Millionen oder Milliarden Dateien ausgeht).

        - Sven Rautenberg

        --
        My sssignature, my preciousssss!
        1. Hallo Sven,

          Typische Applikationen, die unbekannt viele Dateien erzeugen könnten, und deren Dateinamen z.B. Hexzahlen sind,

          Genau so wird es sein! Der Dateiname ist im Grunde eine Argumentliste, der z.B. die Beschriftung des Bildes definiert. D.h. es kann schon vorkommen zwei Leute die selbe Datei mit demselben Namen brauchen.

          Dateiname beginnt mit 0FE3....
          Datei liegt in /prefix/0/F/E/3/0FE3....

          Cool, so werde ich das machen!

          Danke dir,
          Eddie

          --
          Old men and far travelers may lie with authority.
      3. Hi,

        Ihr seht, ich mach das grad zum ersten Mal :-)

        Denk dann auch dran, "Expires"- und "Last-Modified"-Header mitzuliefern und ggf. unnötige Requests mit einem "304"Header zu beantworten, ohne die Bilddaten unnötig durch die Leitung zu pusten ...

        Gruß, Cybaer

        --
        Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
        1. Hallo Cybaer,

          bin mir nicht sicher, ob ich das richtig verstanden habe:

          Denk dann auch dran, "Expires"- und "Last-Modified"-Header mitzuliefern

          Welchem Zweck dient das? "Expires" sollte eigentlich garnicht vorkommen, da die Dateien (egal, ob sie physikalisch existieren oder nicht) dauerhaft gueltig sein werden.
          Und bei "Last-Modified" gilt eigentlich dasselbe: die Dateien koennen nicht verändert werden. Werden sie verändert, dann ändert sich auch der Dateiname (vgl. meine Antwort auf Sven's Beitrag).
          Brauche ich diese Header-Angaben also trotzdem?

          und ggf. unnötige Requests mit einem "304"Header zu beantworten, ohne die Bilddaten unnötig durch die Leitung zu pusten ...

          Oh Gott, wusste ich ja garnicht, dass es sowas gibt, peinlich! Macht der Apache sowas automatisch? Oder muss ich ihn dazu anweisen?

          Also, um mal abzuschweifen: http://www.umdiewelt.de hält zur Zeit ca. 45.000 Bilder parat, die mir monatlich 100GB Traffic bescheren. Wie kann ich feststellen, ob da bereits 304 genutzt wird?

          Eddie

          --
          Old men and far travelers may lie with authority.
          1. Hi,

            Welchem Zweck dient das? "Expires" sollte eigentlich garnicht vorkommen, da die Dateien (egal, ob sie physikalisch existieren oder nicht) dauerhaft gueltig sein werden.

            Umso wichtiger!

            Googel mal nach Expires Cache-Control ...

            Und bei "Last-Modified" gilt eigentlich dasselbe: die Dateien koennen nicht verändert werden. Werden sie verändert, dann ändert sich auch der Dateiname (vgl. meine Antwort auf Sven's Beitrag).

            Umso wichtiger!

            Brauche ich diese Header-Angaben also trotzdem?

            Also wenn Du Traffic sparen (und dem User möglichst wenig Traffic zumuten) möchtest: Ja.

            und ggf. unnötige Requests mit einem "304"Header zu beantworten, ohne die Bilddaten unnötig durch die Leitung zu pusten ...
            Macht der Apache sowas automatisch? Oder muss ich ihn dazu anweisen?

            Der Apache macht das automatisch - bei statischen Dateien. Du generierst den Output on-the-fly - also mußt Du dich auch selbst drum kümmern.

            Wenn Du dem Client sagst, er soll sich bei einem wiederholten Aufruf aus seinem Cache bedienen, dann macht er das ggf. auch. Wenn Du ein Last-Modified- oder ETag-Header schickst, dann fragt sendet der Client beim erneuten Request diese Daten mit, Du kannst dann entscheiden, ob sich die Daten mittlerweile geändert haben, und statt 200 & Daten einen 304 ohne Daten schicken.

            Wenn sich deine Daten aber ohnehin nie nicht ändern, dann kannst Du dir aber vielleicht die Überprüfung auch ersparen (unsauber, aber schnell implementiert ;-)): schick doch einfach ein willkürliches ETag mit, und wenn ein Request mit einer ETag-Nachfrage kommt, dann hat der Client die Daten schon ;->:

              
            <?php  
            if(!empty($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH']=='never-changed') {  
             header('Status: 304 Not Modified');  
             header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');  
             header('Connection: close');  
             die();  
            } else {  
             header('ETag: never-changed');  
             // Hier noch Expires- und Cache-Control-Header nach Wunsch  
             send_data();  
            }  
            ?>  
            
            

            wobei send_data() die Funktion ist, die dann die Bilddaten ausliefert ...

            Also, um mal abzuschweifen: http://www.umdiewelt.de hält zur Zeit ca. 45.000 Bilder parat, die mir monatlich 100GB Traffic bescheren. Wie kann ich feststellen, ob da bereits 304 genutzt wird?

            Im Log steht jeweils der Statuscode des Requests. Z.B. 200 (erfolgreich) inkl. der übertragenen Bytes, oder eben 304, dann üblicherweise ohne Bytes (der Client hatte die Daten ja schon).

            Gruß, Cybaer

            --
            Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
            1. Hallo Cybaer,

              super, danke dir! Das hat mal sehr viel Klarheit geschaffen bei mir :-)

              Der Apache macht das automatisch - bei statischen Dateien. Du generierst den Output on-the-fly - also mußt Du dich auch selbst drum kümmern.

              Im Log steht jeweils der Statuscode des Requests. Z.B. 200 (erfolgreich) inkl. der übertragenen Bytes, oder eben 304, dann üblicherweise ohne Bytes (der Client hatte die Daten ja schon).

              Ok, Entwarnung, ist genau, wie du sagst, ueberall 304er :-)

              Eddie

              --
              Old men and far travelers may lie with authority.
            2. Hi,

              und ggf. unnötige Requests mit einem "304"Header zu beantworten, ohne die Bilddaten unnötig durch die Leitung zu pusten ...
              Macht der Apache sowas automatisch? Oder muss ich ihn dazu anweisen?
              Der Apache macht das automatisch - bei statischen Dateien. Du generierst den Output on-the-fly - also mußt Du dich auch selbst drum kümmern.

              Also nach meinem Vorschlag wären die Dateien statisch - nur, falls eine Graphik nicht existiert, springt das Script ein, das die Datei dann erzeugt ...

              cu,
              Andreas

              --
              Warum nennt sich Andreas hier MudGuard?
              Schreinerei Waechter
              O o ostern ...
              Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
              1. Hallo Andreas,

                Also nach meinem Vorschlag wären die Dateien statisch - nur, falls eine Graphik nicht existiert, springt das Script ein, das die Datei dann erzeugt ...

                Genau! Und in diesem Fall kann ich's ja mit Cybaers Vorschlag kombinieren.

                Eddie

                --
                Old men and far travelers may lie with authority.