Sven: Bilder in Temp-Ordner speichern?

Hey ihr,

gibt es in PHP eine Variable, die das temporäre Verzeichnis von PHP angibt?

Also der Hintergrund ist, dass ich ein Bild nur begrenzt speichern will... eigentlich reicht es schon, dass das Bild direkt nach dem Ende des Scripts wieder gelöscht wird. Extra eine unlink-Anweisung an das Scriptende zu packen, halte ich aber für extremst unflexibel, da es hier um viele Seiten geht, und der Bildname variieren kann.

Kann ich temporäre Bilder nicht einfach im PHP-Temp Verzeichnis abspeichern, und dort werden sie automatisch gelöscht?

Grüße
Sven

  1. Hallo,

    deine Anwendung ist nicht klar. Wenn du per PHP ein Bild erzeugst, dass vom Browser geladen werden soll, muss dieses Bild eine unbestimmte Zeit lang verfügbar sein.

    Wenn du es schneller wieder löscht, als der Browser laden kann, gibt das keinen Sinn.

    Selbst dann, wenn du mit 1 Stunde Verzögerung löscht, gibt es keinen Sinn, dies für alle Bilder zu tun, einschließlich der von weiteren Usern soeben erzeugten und noch nicht geladenen.

    LG Kalle

  2. Hello Sven,

    wenn Du wirklich die Lebensdauer der Datei an die Lebensdauer des Scriptes koppeln möchtest, dann sind zwei Funktionen für Dich wahrscheinlich hilfreich:

    http://de2.php.net/manual/de/function.register-shutdown-function.php
    und
    http://de2.php.net/manual/de/function.tempnam.php

    Mit tempnam() legst Du Dir eine Datei mit einem eindeutigen zufälligen Namen an und mit registger_shutdown_function kannst Du eine "Destructor-Funktion" festlegen, den Du natürlich vorher definieren mussst. Dieser kannst Du als Aufgabe geben, alle in ein Array eingetragenen Dateien zu entfernen.

    Du benötigst also eine "Anmeldefunktion", die die Datei anleget und ihrn Namen in ein Array einträgt und eine Löschfunktion, die bei Aufruft das Array abarbeitet und alle noch vorhandenen Dateien daraus löschst. Die Löschfunktion meldest Du mit register_shutdown_handler() als Exit-Prozudur an.

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

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
    Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

    1. Mit tempnam() legst Du Dir eine Datei mit einem eindeutigen zufälligen Namen an und mit registger_shutdown_function kannst Du eine "Destructor-Funktion" festlegen, den Du natürlich vorher definieren mussst. Dieser kannst Du als Aufgabe geben, alle in ein Array eingetragenen Dateien zu entfernen.

      Du benötigst also eine "Anmeldefunktion", die die Datei anleget und ihrn Namen in ein Array einträgt und eine Löschfunktion, die bei Aufruft das Array abarbeitet und alle noch vorhandenen Dateien daraus löschst. Die Löschfunktion meldest Du mit register_shutdown_handler() als Exit-Prozudur an.

      Danke für diese sehr ausführliche Hilfe! Ich denke, ich müsst es hinbekommen haben. Das Prinzip von register_shutdown_handler() habe ich so verstanden:

      1. Funktion anlegen zum Löschen von Dateien:
      function deleteFile($file) {
        unlink($file);
      }

      2. register_shutdown_handler(deleteFile($tmpfilename));

      3. Fertig (gehen wir mal davon aus, dass der Dateiname in $tmpfilename steht und das Erstellen der Datei/des Bildes schon erledigt ist.

      In dem Fall müsste nach Beendigung des Scripts automatisch die Datei gelöscht werden? Ich habe das grade probiert: Bei einem Aktualisieren kam nur eine zweite Temp-Datei hinzu. Wann gilt das Script denn als beendet?

      Im Moment weiß ich nicht, ob das Script nicht funktioniert, oder ob es nur eine bestimmte Zeit dauert, bis das Script als beendet gilt...

      Vielen Dank!

      Grüße
      Sven

      1. Ah, bei register_shutdown_function() dürfen beim Aufruf der Funktion keine Parameter übergeben werden. Okay, jetzt funzt es. :-)

      2. Hello,

        1. register_shutdown_handler(deleteFile($tmpfilename));

        Wie Du schon gemertk hattest, hatte ich mich da im Eifer des Gefechts mit dem Namen geirrt.

        $ok = register_shutdown_function('deleteFile');

        musste es heißen.

        http://de3.php.net/manual/de/function.register-shutdown-function.php

        Aber das liegt daran, dass der angemeldete Handler gar keine Funktion sein darf.
        Die Prozedur darf weder einen Rückgabewert haben noch kann sie Funktionsargumente übernehmen. Das ist wieder einer dieser typischen Fehlbenennungsfälle in PHP.

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

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau
        Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

        1. echo $begrüßung;

          Aber das liegt daran, dass der angemeldete Handler gar keine Funktion sein darf.
          Die Prozedur darf weder einen Rückgabewert haben noch kann sie Funktionsargumente übernehmen. Das ist wieder einer dieser typischen Fehlbenennungsfälle in PHP.

          "Prozedur" ist Pascal-Sprachgebrauch. In PHP gibt es nur Funktionen, auch wenn die parameterlos sind und keinen Wert zurückgeben.
          register_shutdown_funktion() erwartet den Namen einer Funktion, keinen Funktionsaufruf, denn dann hätte es register_shutdown_funktion_call heißen müssen.

          echo "$verabschiedung $name";

          1. Hello,

            "Prozedur" ist Pascal-Sprachgebrauch.

            Ich dachte eben: den Begriff hat es schon lange vor Pascal gegeben.
            Aber Pascal ist tatscählich schon 1972 entwickelt worden.

            Ich habe noch unabhängig von Pascal gerlernt dass Prozeduren (= Subroutines) mit Originalen arbeiten, während Funktionen instantiiert werden und mit Kopien arbeiten, was auch die rekursive Ausführung ermöglicht. Das vereinfachte Darstellung des damaligen Unterrichtsstoffes.

            Das war so ungefähr 1974. Allerdings hatten wir da Algol 60 und so obskure Sprachen, wie "X1". Die Maschine hieß genauso, auf der sie lief. War dem Algol 60 aber sehr ähnlich.

            Ich finde es trotzdem schade, dass die Art des Aufrufs in der Begrifflichkeit heute verloren gegangen ist. Es ist doch (auch heute noch) ein Unterschied, ob ich eine Funktion aufrufe, die Argumente übernimmt und ein Ergebnis liefert, oder ob ich eine Prozedur (so wie ich es eben immer noch nenne) aufrufe, die auf feste Speicheradressen bzw. fetgelegte Variablennamen zugreift.

            Mit "register_shutdown_function_call" könnte ich Dir glatt zustimmen. Man bräuchte es innerhalb eines Scriptes zum Glück nicht so häufig. Da könnte der Name dann ruhig zum bandwurm mutieren :-))

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

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau
            Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

        2. Hey Tom,

          also ich habs jetzt etwas anders versucht - das Löschen klappt auch, allerdings löscht er es, bevor der Browser das Bild überhaupt laden kann. Hat sich da ein Fehler eingeschlichen oder ist das ganze Konstrukt Müll?

          Ich geb mal kurz das wesentliche wieder:

          // Zufalls-Dateinamen festlegen
          $tmpname = "tmpPic_".rand(100000,999999);
          $tmpname = $tmpname.".png";
          $_SESSION['tmpfile'] = $tmpname; // Dateinamen auch in Session speichern, damit ich in der Delete-Prozedur darauf zugreifen kann

          // Etwas Code, der ein Bild mit dem Namen $tmpname erstellt...
          // ...

          register_shutdown_function("deleteFile");
          // ENDE

          function deleteFile() {
            if($_SESSION['tmpfile']) {
              unlink($path."/".$_SESSION['tmpfile']);
              unset($_SESSION['tmpfile']);
            }
          }

          So... da bei register_shutdown_function() keine Funktionsparameter erlaubt sind, dachte ich, ich löse das über eine Session-Variable (eine Session wird ohnehin gestartet).

          Aber wie gesagt: Im Browser erscheint kein Bild. Kommentiere ich den Aufruf von unlink() aus, erscheint ein Bild. Also scheint er es zu schnell zu löschen...

          Muss ich bei register_shutdown_function zwingend ein Array angeben? Oder wo ist das Problem?

          Gruß
          Sven

          1. Hello Sven,

            also ich habs jetzt etwas anders versucht - das Löschen klappt auch, allerdings löscht er es, bevor der Browser das Bild überhaupt laden kann. Hat sich da ein Fehler eingeschlichen oder ist das ganze Konstrukt Müll?

            Die Frage, was Du mit dem Konstrukt vor hast, wurde Dir doch schon vorher gestellt.

            So... da bei register_shutdown_function() keine Funktionsparameter erlaubt sind, dachte ich, ich löse das über eine Session-Variable (eine Session wird ohnehin gestartet).

            Aber wie gesagt: Im Browser erscheint kein Bild. Kommentiere ich den Aufruf von unlink() aus, erscheint ein Bild. Also scheint er es zu schnell zu löschen...

            Kann vermutlich nicht mehr erscheinen.
            Du musst dem Browser erstmal den Namen des Bildes mitteilen.
            Das tust Du vermutlich in einer HTML-Seite, die eine Image-Referenz enthält:

            <img src="B3456F41AC.jpg" alt="temporäres Bild" />

            Wenn der Browser dieses Stück Code erhält, ist das Bild schon wieder gelöscht.
            Wenn Du unbedingt nur ein temporär gespeichertes Bild ausliefern willst, dann mach es anders:

            Temporärnamen erzeugen

            Bild erzeugen und unter "temporärname.jpg" speichern und unter "temporärname.php" eine Datei nach folgendem Aufbau anlegen:

            <?php

            header('Content-Type: image/jpeg');
            readfile('path/temporärname.jpg');

            unlink('path/temporärname.jpg');
            unlink('temporärname.php');

            ?>

            Wenn Du nun das Bild in einem Verzeichnis speicherst, das per HTTP nicht erreichbar ist, und "temporärname.php" als Bildressource-namen ausliefert, dann kann der Clietn dieses Bild genau einmal abfordern.

            Ob das Ganze sinnvoll ist, lasse ich mal dahingestellt.
            Aber es ist ein nettes Spiel.

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

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau
            Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

            1. Hey Tom,

              okay... ich war grad am Arbeiten an deiner vorgeschlagenen Lösung, als mir dann doch einfiel, wie es fiel leichter geht.

              Es geht eigentlich um die Funktion ImageTTFText(), bei der ich beliebigen Text in einer beliebigen Schriftart als Bild abspeichern kann.

              Hab jetzt eine createPic.php erstellt, in der das Bild direkt ausgegeben wird, ohne dass es in einer Datei abgespeichert wird. Per GET gebe ich den gewünschten Text an... und die Datei gebe ich dann als Quelle bei <img... an.

              Wie einfach die Lösung doch sein kann... :-)

              Thx ;-)
              Sven

              1. Hello,

                Hab jetzt eine createPic.php erstellt, in der das Bild direkt ausgegeben wird, ohne dass es in einer Datei abgespeichert wird. Per GET gebe ich den gewünschten Text an... und die Datei gebe ich dann als Quelle bei <img... an.

                Wie einfach die Lösung doch sein kann... :-)

                Also so?

                <img src="create.Pic.php?str=Hier%20steht%20der%0alange%20Supertext" alt="Supertext" />

                Dann musst Du allerdings damit rechnen, dass sich dieses Tool bald rumspricht (Google Bildersuche) und es jeder in seine Seiten einbaut :-)

                Oder prüfst Du in dem Script auf eine gültige Session?

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

                Tom

                --
                Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                Nur selber lernen macht schlau
                Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

                1. <img src="create.Pic.php?str=Hier%20steht%20der%0alange%20Supertext" alt="Supertext" />

                  Dann musst Du allerdings damit rechnen, dass sich dieses Tool bald rumspricht (Google Bildersuche) und es jeder in seine Seiten einbaut :-)

                  Hm das wäre theoretisch zwar möglich, aber: Ich hab die URL per mod_rewrite geändert, im HTML Quelltext sieht das jetzt so aus: src="pictures/Hier%20der%20Text.png"

                  Außerdem sind Farben (Hintergrund/Vordergrund) so festgelegt, dass sie in mein Layout passen. Aber theoretisch könnte das jemand zweckentfremden, ja... da muss ich gleich mal eine Überprüfung einbauen, Danke!

                  Gruß
                  Sven

                  1. Hi Sven,

                    Hm das wäre theoretisch zwar möglich, aber: Ich hab die URL per mod_rewrite geändert, im HTML Quelltext sieht das jetzt so aus: src="pictures/Hier%20der%20Text.png"

                    Nur weil man es nicht mehr auf den ersten Blick sieht: Man kann dein Script nach wie vor missbrauchen ;-)

                    Außerdem sind Farben (Hintergrund/Vordergrund) so festgelegt, dass sie in mein Layout passen. Aber theoretisch könnte das jemand zweckentfremden, ja... da muss ich gleich mal eine Überprüfung einbauen, Danke!

                    Du hast noch ein ganz anderes Problem - bei jedem Aufruf deines Scripts muss das Bild neu erstellt werden, was sehr performance-lastig ist. Sagen wir mal, du hast pro HTML-Seite 3 solche dynamischen Bilder eingebaut und 10 Leute rufen deine Seite gleichzeitig auf, dann muss dein Server 30 Bilder auf einmal generieren, statt nur 3. Das beansprucht schon eine Menge Arbeitsspeicher und Rechenleistung.

                    Aus diesem Grund solltest du dich mit dem Caching der Bilder auseinandersetzen. Also ein einmal erstelltes Bild nicht nur ausgeben, sondern auch noch auf dem Server speichern, sodass beim nächsten Aufruf desselben Bildes, dieses nicht neu generiert werden muss, sondern einfach aus dem Cache ausgegeben werden kann. Du könntest du das Bild unter dem Dateinamen md5($_GET['str')] abspeichern, dann hast du auch keine Probleme mit Sonderzeichen im Dateisystem oder dem Überschreiben übergeordneter Dateien.

                    Im Allgemeinen, würde ich aber dein Konzept als solches bezweifeln. Wozu musst du Bilder mit Text erstellen? Warum kannst du nicht ein entsprechendes HTML-Element mit CSS formatieren, dass du den gewünschten Effekt erreichst?

                    Einziger in meinen Augen sinnvoller Grund wäre, wenn du sehr exotische Schriftarten verwenden willst, welche auf dem PC des Besuchers nicht installiert sind und Alternativ-Schriftarten nicht in Frage kommen.

                    Viele Grüße,
                      ~ Dennis.

                    1. Hi Sven,

                      Hm das wäre theoretisch zwar möglich, aber: Ich hab die URL per mod_rewrite geändert, im HTML Quelltext sieht das jetzt so aus: src="pictures/Hier%20der%20Text.png"

                      Nur weil man es nicht mehr auf den ersten Blick sieht: Man kann dein Script nach wie vor missbrauchen ;-)

                      Ich werd noch die Session-Daten abfragen, dann sollte es sicher sein ;-)

                      Du hast noch ein ganz anderes Problem - bei jedem Aufruf deines Scripts muss das Bild neu erstellt werden, was sehr performance-lastig ist. Sagen wir mal, du hast pro HTML-Seite 3 solche dynamischen Bilder eingebaut und 10 Leute rufen deine Seite gleichzeitig auf, dann muss dein Server 30 Bilder auf einmal generieren, statt nur 3. Das beansprucht schon eine Menge Arbeitsspeicher und Rechenleistung.

                      Hmm... aber jede Grafik in Photoshop zu erstellen und auf den Webserver zu laden, ist auch eine miese Lösung. Aber kommen wir erstmal zum nächsten Punkt...

                      Einziger in meinen Augen sinnvoller Grund wäre, wenn du sehr exotische Schriftarten verwenden willst, welche auf dem PC des Besuchers nicht installiert sind und Alternativ-Schriftarten nicht in Frage kommen.

                      So siehts aus. Ich möchte derartige Überschriften (h3-Überschriften) gerne in der Schrift formatieren, die auch für das Logo verwendet wurde. Es sieht einfach schick und modern aus... ich habs mit Verdana, Arial, Helvetica, ... probiert, aber das wirkt einfach nicht. Da müsste ich dann das Layout an sich etwas ändern und eigentlich gefällt es mir so ziemlich gut.

                      Es handelt sich ohnehin um ein neues Portal... wir haben ein paar zahlende Kunden, mit denen wir die Serverkosten graaad so gedeckt kriegen, und die erwarten eine Veröffentlichung noch diesen Monat. Wenn die Nutzerzahlen ansteigen, werde ich mich um das Thema Optimierung nochmal separat kümmern und dabei sicher auch auf dieses Thema kommen... und dann entweder über das angesprochene Caching nachdenken (Danke!), oder überhaupt diese Variante ganz über Bord werfen.

                      Ich bin erstmal ganz froh, dass es funktioniert... vielleicht mach ich aber die Überschriften auf den einzelnen Seiten auch wirklich als feste Bilddatei und werde diese dynamische Variante nur in den Profilseiten verwenden, wo das Pseudonym auf diese Weise dargestellt wird. Das dürfte ihn dann schon entlasten...

                      Grüße
                      Sven