PHP-Script soll waren bis Bild kopiert ist

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • PHP-Script soll waren bis Bild kopiert ist

    Hallo!

    Ich habe folgende Problemstellung: Ein PHP-Script kopiert ein Bild 1 von einer Quelle in ein Zielverzeichnis (ist dann Bild 2), um dort dann in das kopierte Bild 2 ein weiteres Bild 3 mittels imagecopy einzufügen. Nun hat sich das Problem ergeben, dass manchmal anscheinend der Kopiervorgang länger dauert und daher das Script "zu schnell" fertig ist, also das mittels imagecopy einzufügende Bild 3 nicht in das kopierte Bild 2 eingefügt werden kann, weil Bild 2 noch nicht existiert (es wurde noch nicht vollständig kopiert) und dann bekomme ich einen Fehler, dass das Bild 2 nicht geladen werden kann.

    Kann mir vielleicht jemand weiter helfen, wie ich das Script dazu veranlasse so lange zu warten, bis das Bild existiert?

    Eine Idee wäre vielleicht eine while-Schleife, die so lange durchlaufen wird, bis das Bild existiert und immer mittels usleep() eine halbe Sekunde wartet... Aber ich weiß nicht, ob das elegant ist und ob das nicht sehr resourcenintensiv ist...

    Danke für eure Hilfe!

  • #2
    Das was du beschreibst, kann in einem PHP Script nicht passieren.
    PHP Funktionen sind atomar und werden sequentiell abgearbeitet.

    Es sei denn du veranstaltest da ganz lustige Aktionen.
    Aber das bleibt ja geheim.
    Zuletzt geändert von combie; 09.02.2013, 13:52.
    Wir werden alle sterben

    Kommentar


    • #3
      Hallo combie,

      erstmal danke für deine Antwort!

      Ich weiß, dass ein Script von oben nach unten abgearbeitet wird - ich nehme an, dass du das mit "sequentiell" meinst. Aber kann es nicht folgenden Ablauf in einem Script geben:

      1. Bild 1 wird aus Quelle in ein Zielverzeichnis kopiert > es entsteht Bild 2 im Zielverzeichnis (ist ident mit Bild 1)
      2. Ein Bild 3 wird in das neu erstellte Bild 2 mittels imagecopy() hineinkopiert.

      Nun würde ich gerne wissen, ob
      a) das Script zwar den "Auftrag" zum Kopieren von Bild 1 nach Bild 2 gibt, aber dieses das Betriebssystem erst ausführen muss, also das Erstellen der Datei ein Prozess ist, der unabhängig vom Script läuft und somit im Script weiter unten möglicherweise der Kopiervorgang noch nicht abgeschlossen ist, was dazu führt, dass das Bild nicht für weitere Operationen zur Verfügung steht

      oder

      b) das Script das Bild erstellt (also z.B. mittels ImageCreateFromJPEG) und das Script erst dann weiter läuft, wenn die Datei vollständig erstellt ist?

      Es mag merkwürdig klingen, was ich hier frage, aber ich komme auf diesen Gedanken, weil mein Script einen Fileupload enthält. Nun kommt es manchmal vor, dass der Fileupload und das imagecopy wunderbar funktionieren, manchmal aber folgende Fehlermeldung angezeigt wird:

      Warning: imagejpeg(): Unable to open [Pfad zur Zieldatei inkl. Dateiname] for writing: Invalid argument in script.php on line X

      Der Code des Script ist schemenhaft ca. so:

      PHP-Code:
      // Originalbild wird kopiert (Bild 1 > Bild 2)
      $source_original = [Dateipfad Dateiname von Bild 1];
      $target_path = [Dateipfad Dateiname von Bild 2];
      $source_res ImageCreateFromJPEG($source_original);
      $copy_source_picture imagejpeg($source_res$target_path100);

      // nun wird die Quelle für Bild 3 angegeben, das in Bild 2 hineinkopiert werden soll
      $source_bild3 = [Dateipfad Dateiname von Bild 3];
      $destination_bild2 = [Dateipfad Dateiname von Bild 2]; // ist der gleiche wie $target_path weiter oben
      $source_bild3_res ImageCreateFromJPEG($source_bild3);
      $destination_bild2_res ImageCreateFromJPEG($destination_bild2);

      // nun wird Bild 3 in Bild 2 kopiert
      $copy imagecopy ($destination_bild2_res$source_bild3_res, ... x-y-Werte Höhe Breite usw.);

      // auf Basis von $destination_bild2_res wird ein Bild abgespeichert
      $destination_save_path Dateipfad für das fertige Bild (inklDateiname)
      $save  imagejpeg ($destination_bild2_res$destination_save_path100); //  <--dies ist Zeile X, die die o.g. Warning-Fehlermeldung bewirkt 
      Ich hoffe, dass ich das Problem beschreiben konnte. Das Problem ist, dass mein Script eben manchmal problemlos funktioniert und beim nächsten Mal wieder nicht, obwohl ich immer die selbe Datei hochladen will - einmal wird sie korrekt hochgeladen und in das Zielbild integriert, manchmal erhalte ich den Warning-Fehler.

      Danke für eure Hilfe!

      Kommentar


      • #4
        Nicht das lesen schlägt fehl, sondern das schreiben....

        Also sicherlich ein Rechte oder Pfad Erstellungsproblem.
        Wir werden alle sterben

        Kommentar


        • #5
          Ja, du hast Recht, das Schreiben scheint das Problem zu sein, aber wie kann es sein, dass es einmal oder manchmal 5x hintereinander funktioniert und beim sechsen Mal ein paar Sekunden später nicht mehr? Hast du eine Idee?

          Ich habe nun testweise ein sleep(2) nach dem Kopieren des Originalbildes eingefügt und nun tritt der Fehler nicht mehr auf... Aber das kann ja nicht die Lösung sein. Ich habe auch schon versucht, alle Dateipfade, die vorkommen, mittels file_exists() zu prüfen - auch das ergibt immer TRUE - auch wenn der Writing-Fehler auftritt (was eh klar ist, weil anscheinend die Datei zwar existiert, aber ein Schreibproblem existiert)...

          Bei meinem Beitrag vorhin - ist es so, dass PHP eben das Script von oben nach unten abarbeitet und somit wartet, bis jeder Befehl vollständig ausgeführt ist? (also Option b)?

          Hast du eine andere Idee? Ich entwickle unter IIS 8 (Windows 8) lokal auf meinem Rechner.

          Danke für deine Hilfe!

          Kommentar


          • #6
            Du könntest solange eine Schleife durchlaufen (mit ggf. kleinem usleep(); drin) bis PHP: is_writable - Manual true liefert und dann deine zweite Aktion starten.
            Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
            Schön - etwas Geschichte kann ja nicht schaden.
            Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

            Kommentar


            • #7
              Hallo Quetschi,

              danke für deine Antwort! Sie klang nach Lösung für mein Problem, jedoch funktioniert leider auch diese Variante nicht. Ich habe zwar auch eine While-Schleife versucht, aber selbst ein simples

              PHP-Code:
              if (is_writable($destination_save_path)) imagejpeg... // also imagejpeg nur dann ausführen, wenn $destination_save_path writeable ist 
              gibt immer TRUE zurück, auch wenn ich danach den Fehler bekomme. Also es verhält sich so wie file_exists() - sowohl file_exists() als auch is_writable() für meine Zieldatei geben immer TRUE zurück, auch wenn es danach zu einem Fehler kommt...

              Langsam weiß ich nicht mehr weiter...

              Hat noch jemand eine Idee?

              Kommentar


              • #8
                Wie sieht der Dateipfad aus?

                Kommentar


                • #9
                  1. das beschriebene Problem kann kein PHP Problem sein. Pfad (manchmal) falsch, ok, oder evtl. auch ein OS Problem. Aber nicht PHP, denn PHP arbeitet atomar und sequentiell. Aber das sagte ich doch schon.
                  2. is_writable() in einer While Schleife ist völliger Unsinn, wenn es ohne clearstatcache() daher kommt.
                  3. der sleep() ist völlig sinnfrei, Begründing siehe Punkt 1.
                  Wir werden alle sterben

                  Kommentar


                  • #10
                    Hallo h3ll,

                    ein Beispiel für den Dateipfad wäre: user_data/assemblies/8/upload/113/bild1.jpg.

                    Sieht für mich sehr unauffällig aus - keine unzulässigen Zeichen... Ich wähle auch immer wieder die selben Dateien für den Upload aus, das heißt auch für die selbe Grafik bekomme ich mal einen Fehler, mal keinen...

                    @combie

                    Danke für deine Rückmeldung!!

                    Wie ich gerade an h3ll geschrieben habe, passiert auch bei der selben Datei manchmal ein Fehler, manchmal nicht. Wie meinst du, dass der Pfad dann "manchmal" falsch sein kann? Meinst du damit etwas bestimmtes?

                    Kann ich den Test mit is_writable() machen, wenn ich clearstatcache() verwende? Ist es dann sinnvoll?

                    Also ca. so:

                    PHP-Code:
                    while (!is_writable($destination_save_path))
                    {
                         
                    usleep(250000);
                         
                    clearstatcache();
                    }
                    $save imagejpeg ($destination_bild2_res$destination_save_path100); // also imagejpeg erst ausführen, nachdem vorher writeable geprüft wurde 
                    Danke!

                    Kommentar


                    • #11
                      Meinst du damit etwas bestimmtes?
                      Ich meine etwas bestimmtes!

                      Und zwar: Du suchst am falschen Ende!
                      Du hast dir da einen Fehler ausgedacht, und kommst nicht mehr davon runter.
                      Festgebissen am "PHP schreibt verzögert".
                      Und das ist falsch. Ganz falsch, völlig falsch. Irre falsch.
                      Und solange du da nicht von weg kommst wirst du den Fehler nie finden.


                      Wie ich es machen würde:
                      Da ich weiß, dass PHP bei allen Schreiboperationen die selben cLib Funktionen nutzt, würde ich erst mal die ganzen Image Hampeleien raus werfen. Der Fehler muss sich mit einem einfachen fopen, oder file_put_contents reproduzieren lassen.

                      Also, zurück brechen auf eine ganz einfache Script Struktur.

                      Zweiter Ansatz:
                      Da PHP selber kein Multitasking/Multithreading kann, wird das vom Webserver (oder OS) verwaltet. Es also wäre evtl. möglich, dass dir Race Conditions ein Beinchen stellen. Das über (u)sleep() lösen zu wollen ist nur bedingt hilfreich. Interessanter wäre die Arbeit mit Lockdateien um dieses Problem im Keim zu ersticken.
                      Wir werden alle sterben

                      Kommentar


                      • #12
                        *Kopfkratz*

                        combie hat da natürlich schon recht - und die Verwendung von clearstatcache hab ich einfach mal vorausgesetzt, weils ja im Manual groß genug drinstehen würd.

                        Ich bin grad aber nochmal am genauen Wortlaut der Fehlermeldung hängengeblieben.

                        Lass dir doch mal ausgeben was in $destination_save_path steht, wenn der Fehler auftritt.
                        Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                        Schön - etwas Geschichte kann ja nicht schaden.
                        Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                        Kommentar


                        • #13
                          Hallo und entschuldigt bitte die späte Rückmeldung...

                          Vielen Dank für eure neuen Antworten!

                          @combie
                          Okay, dann werde ich mal deinem Rat folgen und das Script zerlegen und neu beginnen.
                          Das mit Lockdateien habe ich mal am Rande gelesen - meinst du die Funktion flock() ?

                          Den Tipp mit clearstatcache() habe ich umgesetzt - der hat leider auch keinen Erfolg gezeigt - nur zur Info, aber ich weiß ja, dass du die Variante mit usleep() nicht gut findest... Aber ich wollte es nur ergänzend sagen.

                          @Quetschi

                          Den Pfad, der in $destination_save_path enthalten ist, habe ich mir natürlich schon ausgeben lassen - er passt, also da steht genau der richtige Pfad drinnen - ohne Leerzeichen und ohne Fehler.

                          Aber danke euch beiden mal für eure Rückmeldungen. Mir wird es wohl nicht erspart bleiben, das Ganze von Grund auf noch einmal aufzuziehen... Ich melde mich, sobald ich Näheres weiß!

                          Kommentar

                          Lädt...
                          X