Emanuel: Problem beim löschen von Bilddateien

Hallo!

Ich bin auf ein für mich unverständliches Problem gestoßen.

Hab habe die Möglichkeit, ein Bild hochzuladen. Mit Hilfe von PHP wird eine ID generiert, das Bild wird mit dieser ID in einem Ordner abgelegt. Die ID und die Dateiendung werden zusätzlich in einer DB hinterlegt.

Mit einer Checkbox ist es zusätzlich möglich, das Bild wieder zu löschen.

Prinzipiell funktioniert das ganze auch, das hochgeladene Bild wird angezeigt, das Bild befindet sich im vorgesehenen Ordner und die Daten stehn auch in der DB.
Das Bild wird auch richtig gelöscht, ist im Ordner nicht mehr sichtbar und die Daten werden aus der DB korrekt entfernt.

Interessanterweise ist es aber macnhmal beim löchen so, dass das Bild nicht entfernt wird und auch die Daten in der DB nicht gelöscht werden, obwohl der Ablauf unverändert ist. Es handelt sich sogar um das gleiche Bild. Wenn ich in die Löschfunktion ein "echo 'test';" einsetze um zu sehen, wo ich mich im Code befinde, wird das Bild IMMER gelöscht. Ohne dem "echo" passiert es manchmal, dass das Bild nicht gelöscht wird.

Gibts dazu irgendeine Erklärung? Ich für meinen Teil habe keine Ahnung wieso das vorkommt.

MfG Emanuel

  1. Ohne einen Code-Ausschnitt, wohl kaum.
    Grüße.

    1. Ohne einen Code-Ausschnitt, wohl kaum.

      Stimmt wohl... im wesentlichen ist es das hier:

        
      <?  
      //   FUNCTIONS  
      function uploadPicture($filename, $filetype, $filesize, $filetmpname, $fileerror, $tmp_pic_id = ''){  
       //Dateiendung  
       $exts = explode(".", basename($filename));  
       $file_extension = strtolower($exts[sizeof($exts)-1]);  
        
       //Check Picture  
       .  
       .  
       .  
       //End Check  
        
       move_uploaded_file($filetmpname, 'images/' . $tmp_pic_id . '_temp.' . $file_extension)  
        
       //Daten in DB eintragen  
        
       return $file_extension;  
      }  
        
      function delPicture($pic_id){  
        
       //hole Dateiendung aus DB --> $file_extension  
       //Lösche Daten aus DB  
        
       if(file_exists('images/' . $tmp_pic_id . '_temp.' . $file_extension))  
        unlink('images/' . $tmp_pic_id . '_temp.' . $file_extension);  
        
      }  
        
      $tmp_pic_id = '';  
      $image = '';  
        
      if(isset($_FILES['pic_upload'])){  
       if(!isset($_POST['tmp_pic_id']))  
        $tmp_pic_id = createUniqueTempID();  
       else  
        $tmp_pic_id = $_POST['tmp_pic_id'];  
        
       $file_extension = '';  
        
       if($_FILES['pic_upload']['error'] != 4 && $_FILES['pic_upload']['size'] != 0)  
        $file_extension = uploadPicture($_FILES['pic_upload']['name'], $_FILES['pic_upload']['type'], $_FILES['pic_upload']['size'], $_FILES['pic_upload']['tmp_name'], $_FILES['pic_upload']['error'], $tmp_pic_id);  
        
       if($file_extension){  
        if(file_exists('images/' . $tmp_pic_id . '_temp.' . $file_extension))  
         $image = 'images/' . $tmp_pic_id . '_temp.' . $file_extension;  
       }  
        
      }elseif(isset($_POST['del_tmp_picture'])){  
       if(isset($_POST['tmp_pic_id']))  
        $tmp_pic_id = $_POST['tmp_pic_id'];  
       else  
        $tmp_pic_id = 0;  
        
       delPicture($tmp_pic_id);  
        
       $image = '';  
       $tmp_pic_id = '';  
      }  
      ?>  
      
      
        
      <html>  
      <body>  
      <?if($image){?>  
       <img src="<?echo $image;?>" alt="Bild">  
      <?}else{?>  
       <img src="images/noimage.png" alt="kein Bild">  
      <?}?>  
      <form action="" method="post" enctype="multipart/form-data">  
      <?if($image){?>  
       <input type="checkbox" name="del_tmp_picture" onchange="submit()"> Bild nicht hinzuf&uuml;gen<br><br>  
      <?}?>  
      Bild: <input type="file" name="pic_upload" size="40" onchange="submit()"><br>  
      <?if($tmp_pic_id){?>  
       <input type="hidden" name="tmp_pic_id" value="<?echo $tmp_pic_id?>">  
      <?}?>  
      </form>  
      </body>  
      </html>  
      
      

      Vielleicht hilft das ja weiter!

      1. function delPicture($pic_id){

        //hole Dateiendung aus DB --> $file_extension
        //Lösche Daten aus DB

        if(file_exists('images/' . $tmp_pic_id . '_temp.' . $file_extension))
          unlink('images/' . $tmp_pic_id . '_temp.' . $file_extension);

        }

        Hab mich hier verschrieben, statt $pic_id muss da natürlich $tmp_pic_id stehen (function delPicture($tmp_pic_id){)

        Das hat aber nichts mit dem eigentlichen Problem zu tun ;)

      2. Wenn ich zugegebenermaßen nur oberflächlich drübergelesen habe, so fällt mir folgendes an deiner Löschfunktion auf: Du prüfst nicht auf Les- geschweige denn Schreibbarkeit deiner Datei. Das würde mit is_writeable() erfolgen. Solange du das nicht machst, nutzt dir das Prüfen auf das Vorhandensein wenig zum Nachweis, ob deine Funktion "geklappt" hat.

        Hast du jetzt, so mein Verdacht, eine Datei manuell in den Ordner kopiert ist der Benutzer, den PHP verwendet nicht der Besitzer der Datei und kann sie folglich auch nicht löschen. Du hast also ein Problem mit chmod. Liege ich mit meinem Verdacht richtig? Voraussetzung ist natürlich ein Linux/Unix-Betriebssystem.

        Was ich dir jedenfalls definitiv sagen kann: ein echo-Befehl hat nichts damit zu tun, so lange dein Server nicht sehr, sehr seltsam konfiguriert ist. Und falls doch, Abhilfe würde dann vorerst wohl auch ein echo '' schaffen.

        PS: Auch unlink() gibt im Erfolgsfall 'true' zurück. Ein weiterer Indikator für den Erfolg deines Löschversuchs.

        1. Liege ich mit meinem Verdacht richtig?

          Nein leider nicht, die Bilder werden über den HTML Teil geladen und mittels PHP im Ordner abgelegt.

          Es kann doch nicht sein, dass es einmal funktioniert und bei einem zweiten oder dritten Versuch (mit dem gleichen Bild und sonst nichts anders gemacht) es nicht funktioniert? (um beim vierten mal dann wieder doch)

          Naja, ich werde das mal weiter beobachten, trotzdem danke!

          Voraussetzung ist natürlich ein Linux/Unix-Betriebssystem.

          Ich verwende WinXP SP2 (ist aber nur local ein Testserver)

          so lange dein Server nicht sehr, sehr seltsam konfiguriert ist

          Habe Apache laufen mit der Standardkonfig.

          PS: Auch unlink() gibt im Erfolgsfall 'true' zurück. Ein weiterer Indikator für den Erfolg deines Löschversuchs.

          Ein Indikator ist auch das Vorhandensein des Bildes im Ordner und die nicht gelöschten Daten in der DB :/

          1. Habe den Fehler gefunden!
            Eigentlich dumm von mir...

            Die Bild_id wird in der Funktion uniqueid erstellt die u.a. mit md5 arbeitet. Der resultierende String enthält 32 Zeichen mit Buchstaben und Zahlen.

            Dummerweise habe ich bei der Funktion delPic folgenden Fehler gemacht:

              
            function delPic($tmp_pic_id = 0){  
              if($tmp_ic_id != 0){  
                --weiterer code--  
              }  
            }  
            
            

            Die Abfrage von $tmp_pic_id darf nicht auf '0' erfolgen (if(.. != 0)), weil der String ja auch Buchstaben beinhaltet.
            Hab das ganze jetzt darauf geändert und es funktioniert:

              
            function delPic($tmp_pic_id = ''){  
              if($tmp_ic_id != ''){  
                --weiterer code--  
              }  
            }  
            
            

            Danke für die Hilfe!

            MfG Emanuel

          2. Es kann doch nicht sein, dass es einmal funktioniert und bei einem zweiten oder dritten Versuch (mit dem gleichen Bild und sonst nichts anders gemacht) es nicht funktioniert? (um beim vierten mal dann wieder doch)

            Nein. Eigentlich nicht, zumindest nich bei dem gleichen Bild.

            Ein Indikator ist auch das Vorhandensein des Bildes im Ordner und die nicht gelöschten Daten in der DB :/

            Sofern dir unlink allerdings false auswirft, ist das etwas, dem du nachgehen solltest. Probiere doch einmal per var_dump(), was dir beim Auftreten des Problemes hier ausgegeben wird. Ich vermute schwer es ist false.