2016-07-22 13 views
0

Ich habe ein Formular, wo der Benutzer Daten eingibt und ein Bild hochlädt. Dieses Bild wird überprüft, ob ein Bild vorhanden ist, das beim md5-Hashing exakt gleich ist. Jedes Bild, das hochgeladen wird, hat seinen eigenen MD5-Hash-Code. Wenn ein Benutzer sich entscheidet, ein Bild hochzuladen, das genau dem Bild auf dem Server entspricht, wird dieses Bild nicht verschoben. Stattdessen erbt das Bild beim Erstellen des Eintrags den Namen dieser Datei aus dem anderen Eintrag mit dem gleichen Hash-Code. Aber ich stoße auf einige Probleme mit meinem aktuellen Code. Zum einen, wenn der Benutzer ein Bild zum ersten Mal hochlädt, gibt es keinen Hash-Code. Ein anderes Problem, das ich mit meinem Code habe, ist, dass selbst wenn ich ein Bild mit dem gleichen Hash-Code hochlade, der Name des Bildes zu einem uniqid wird. Es führt den else-Block und nicht den if-Block aus.Verhindern von Image-Duplikaten auf Server

Hier ist mein Code:

PHP

if (isset($_POST["pageNum"], $_FILES["image"], $_POST["subtitle"], $_POST["text"])) 
    { 
     $page = $_POST["pageNum"]; 
     $url = $_SESSION["articleUrl"]; 
     $subtitle = filter_data($_POST["subtitle"]); 
     $text = filter_data($_POST["text"]); 

     $name = $_FILES["image"]["name"]; 
     $tempName = $_FILES["image"]["tmp_name"]; 

     $target_file = $_SERVER['DOCUMENT_ROOT'] . "/stories/media/images/$name"; 

     $hash = md5_file($target_file); 
     $resultHash = $db->query("SELECT * COUNT(*) FROM `Stories` WHERE hash = '$hash' LIMIT 1"); 

     if ($resultHash->num_rows > 0) 
     { 
      $row = $resultHash->fetch_array(); 
      $name = $row["image"]; 

     } 

     else 
     { 
      if (@getimagesize($target_file) == true) 
        { 
         $ext = pathinfo($name, PATHINFO_EXTENSION);  
         $name = basename($name, "." . $ext); 
         $name = $name . uniqid() . "." . $ext; 
         $target_file = $_SERVER['DOCUMENT_ROOT'] . "/stories/media/images/$name"; 
        } 

      move_uploaded_file($tempName, $target_file); 
     } 

     $result = $db->query("SELECT * FROM Stories WHERE page = '$page' AND url = '$url'"); 

     if ($result->num_rows == 0) 
     { 
      $db->query("INSERT INTO `Stories` (`image`, `text`, `url`, `subtitle`, `page`, `hash`) VALUES ('$name', '$text', '$url', '$subtitle', '$page', '$hash')"); 
     } 

     else 
     { 
      $db->query("UPDATE Stories SET image = '$name', text = '$text', url = '$url', subtitle = '$subtitle', page = '$page', hash = '$hash' WHERE url = '$url' AND page = '$page'"); 
     } 

    } 

Antwort

0

Die folgenden Zeilen sind problematisch, weil Sie nur einen Hash erhalten, wenn die $target_file bereits vorhanden ist. Wenn es keine Datei mit diesem Namen gibt, gibt es nichts zu hacken und Sie können keinen Hash erhalten, der mit dem DB-Wert verglichen wird.

$target_file = $_SERVER['DOCUMENT_ROOT'] . "/stories/media/images/$name"; 
$hash = md5_file($target_file); 

Die erste Zeile ist nutzlos; entfernen Sie es. Sie sollten die Hash-Wert der neu hochgeladenen Datei stattdessen Berechnung, weil das ist, was mit dem in der DB gespeichert Hashes verglichen werden muss:

$hash = md5_file($tempName); 

Später müssen Sie auch Ihre getimagesize Prüfung ändern mit dem neu hochgeladen arbeiten Datei, da diese die Datei, die verarbeitet werden muss (wir um dies zu überprüfen, wenn es sich um eine neue, einzigartige Datei):

if (getimagesize($tempName) == true) 
+0

Als ich das Bild zum ersten Mal laden, wird die getimagesize für einige aufgerufen wird Grund (obwohl die Datei nicht auf dem Server ist). Wenn ich das gleiche Bild noch einmal hochlade, wird der if-Block nicht aufgerufen, um zu überprüfen, ob Zeilen mit dem Hash-Namen vorhanden sind. – user2896120

+0

Ich habe seit der ersten Veröffentlichung einige Änderungen vorgenommen. Könntest du nochmal mit meinen neuesten Empfehlungen testen? Könnte hilfreich sein, einige 'echo' oder' vardump' Aufrufe an Schlüsselstellen hinzuzufügen, um eine Vorstellung davon zu bekommen, was PHP während der Ausführung sieht. – BeetleJuice

+0

Ja, selbst mit den Änderungen bekomme ich das gleiche Ergebnis. Wenn ich $ target_file anstelle von $ tempName in der getimagesize benutze, funktioniert es korrekt und ändert den Bildnamen nicht, wenn ich es zum ersten Mal hochlade. – user2896120