Bereits vorhandene MD5 Summen nicht mehr in die DB schreiben

zkmlch

Master of Disaster
Hallo liebe Tutorianer

Habe ein PHP / MySQL Problem; Ich mache Gerade einen Downloadmanager für meine Webseite, dazu möchte Ich so viel wie möglich automatisieren.

Ich verzweifle langsam aber sicher beim kleinen Generator Script, welches dazu Dient die Files im Ordner /www/downloads/ liegen, mit einer MD5 (md5_file) Summe zu versehen und in die Datenbanktabelle (db_filemanager --> tbl_files zu schreiben) Ziel: Wenn neue files in der Ordner geladen werden soll das Script nur die neuen Files, anhand der MD5 Summe in die Tabelle schreiben. Anderenfalls soll dieser die Files auflisten welche er schon in der Datenbank eingetragen hat...

Nun mein Problem: Ich habe Total 48 Dateien in dem Ordner "Downloads" das Script gibt aber nur 25 Dateien eine MD5 Summe. Wiso macht dieses Script das? Dann hat es bei dem Eintrag in die Datenbank noch einen Schönheitsfehler... er generiert pro durchlauf zwei Tabelleneinträge mit dem wert . & .. Wie krieg Ich das noch weg?

Es folgt nun das generator.php Script:

PHP:
<?php
	//Datenbank-Login
    	$mysqlhost="localhost"; // MySQL-Host angeben
	$mysqluser="****"; // MySQL-User angeben
	$mysqlpwd="****"; // Passwort angeben
	$mysqldb="db_filemanager"; // Gewuenschte Datenbank
     
	//Mit Datenbank Verbinden
    	$connection=mysql_connect($mysqlhost, $mysqluser, $mysqlpwd) or die ("Verbindungsversuch fehlgeschlagen");
     
	//Datenbank auswählen
    	mysql_select_db($mysqldb, $connection) or die("Konnte die Datenbank nicht waehlen.");

	//Variabel für das Auslesen aller Files"
	$sql_files = "SELECT * FROM tbl_files";
	//Öffnet eine persistente Verbindung mit der MySQL Datenbank im zusamenhang mit Browser
	$files_query = mysql_query($sql_files) or die("Anfrage nicht erfolgreich");
	

?>


<?php

$fp=opendir('.');					// Öffnet das aktuelle Verzeichnis /. In diesem Fall /www/downloads/
while(false !== ($datei = readdir($fp))) { 		// Mach so lang die runden bis das Verzeichnis durchgelesen ist!
$chksum = md5_file($datei);				// Generierung der MD Summen
$status = ('N');    					// Statusvergabe --> N für New und Unbearbeitet  


// Nun sollte die DB geprüft werden ob Sie die MD Summe bereits enthaltet...
$result = mysql_query("SELECT * FROM `tbl_files` WHERE `software_md5sum` = '".$chksum."'");
$check = mysql_fetch_row($result);
// ...falls ja, fertig & Echo ausgabe!
if($check != '') die('Eintrag bereits vorhanden');
// ...anderenfalls INSERT der Daten in die Tabelle der DB
else mysql_query("INSERT INTO `tbl_files` (`software_filename` , `software_status` , `software_md5sum`) VALUES ('$datei' , '$status' , '$chksum')") or die(mysql_error());

		
}

closedir($fp);							// Schliesst das Verzeichnis



?>

Im Anhang ist noch der erstellte Datenbankeintrag...

Ich bedanke mich bereits im Vorraus für die wertvolle Hilfe.

Gruss Patrick
 

Anhänge

  • Bildschirmfoto3.png
    Bildschirmfoto3.png
    15 KB · Aufrufe: 23
Zuletzt bearbeitet:
item: ich musste zuerst mal dein Code formatieren um zu sehen wo die Schleife beginnen und Enden

item: Um zu prüfen ob die Datei bereits drin ist, solltest du besser mit mysql_num_rows() orüfen
PHP:
	if(mysql_num_rows($result) > 0) die ('Eintrag bereits vorhanden');
 
Danke für deine Antwort Yaslaw

Leider bekomme Ich immer noch das selbe Resultat... :( Zur Vervollständigung hier nochmals das Script mit den Anpassungen... + Optisch Formatiert


PHP:
<?php

$mysqlhost="localhost"; 
$mysqluser="****"; 
$mysqlpwd="****"; 
$mysqldb="db_filemanager"; 
     
$connection=mysql_connect($mysqlhost, $mysqluser, $mysqlpwd) or die ("Verbindungsversuch fehlgeschlagen");
     
mysql_select_db($mysqldb, $connection) or die("Konnte die Datenbank nicht waehlen.");
$sql_files = "SELECT * FROM tbl_files";
$files_query = mysql_query($sql_files) or die("Anfrage nicht erfolgreich");	
?>

<?php

$fp=opendir('.');		

while(false !== ($datei = readdir($fp))) 

     { 		
              $chksum = md5_file($datei);				
              $status = ('N');    					

              $result = mysql_query("SELECT * FROM `tbl_files` WHERE `software_md5sum` = '".$chksum."'");
              $check = mysql_fetch_row($result);

              if(mysql_num_rows($result) > 0) die ('Eintrag bereits vorhanden'); 

              else mysql_query("INSERT INTO `tbl_files` (`software_filename` , `software_status` , `software_md5sum`) VALUES ('$datei' , '$status' , '$chksum')") or die(mysql_error());

		
       }

closedir($fp);							

?>

Gruss Patrick
 
Zuletzt bearbeitet:
Ich würde das auf DB-Ebene lösen : einfach die Tabelle mit den Hashes als UNIQUE makieren ... so bald du nun versuchst den selben Wert 2 mal einzutragen bekommst du einen ERROR *den du abfangen musst* von der DB das es nicht möglich ist da der Hash bereits vorhanden ist.
Es ist einfach auf einen ERROR zu reagieren als selbst umständlich in der DB zu suchen ...
 
item: Da du beim check auf einen 'die' gehst, wird das Script neim ersten doppelten abgebrochen

item: md5_file() liefert für 2 Files mit verschiedenen Namen und gleichem Inhalt denselben Wert.

Im folgenden Scriptausschnitt werden beide Probleme behoben
PHP:
$dh=opendir($path);        
while(($datei = readdir($dh)) !== false){  
    if($datei != '.' && $datei != '..' && !is_dir($datei)){    
        $chksum = md5_file(createPath($path,$datei));                
        $status = ('N');                        
        
        $sql = "SELECT * 
                FROM `tbl_files` 
                WHERE `software_md5sum` = '{$chksum}'
                    AND `software_filename` = '{$datei}';";
        $result = mysql_query($sql);
        if(mysql_num_rows($result) > 0){
            echo 'Eintrag bereits vorhanden';
        }else{
            $sql = "INSERT INTO `tbl_files` (`software_filename` , `software_status` , `software_md5sum`) 
                    VALUES ('{$datei}' , '{$status}' , '{$chksum}{$file}';)";
            $result = mysql_query($sql) or die(mysql_error());
        }

    }
}
closedir($fp);
 
Ich würde das auf DB-Ebene lösen : einfach die Tabelle mit den Hashes als UNIQUE makieren ... so bald du nun versuchst den selben Wert 2 mal einzutragen bekommst du einen ERROR *den du abfangen musst* von der DB das es nicht möglich ist da der Hash bereits vorhanden ist.
Es ist einfach auf einen ERROR zu reagieren als selbst umständlich in der DB zu suchen ...

Leider ist doch die UNIQUE Methode nur bei reinen Zahlen (INTEGER) möglich, oder irr ich mich da?
 
Ähm .. also man kann UNIQUE nun nicht auf ALLE Datentypen anwenden *z.B. NICHT auf BLOB* ... aber auf VARCHAR geht es ... das weis ich weil ich es in zwei meiner Tabellen selbst drin habe. Zumindest unter MySQL ist das möglich ... ansonsten versuch es mal mit PRIMARY_KEY ... erfüllt die selbe Aufgabe und meldet auch Fehler wenn du versuchst einen Wert doppelt einzutragen.
 
Hallo Yaslaw & SPiKEe

zu Yaslaw's Lösung:

Habe deinen Code 1:1 übernommen und unterhalb des DB-Connect eingefügt. Ergebnis:

Code:
Notice: Undefined variable: path in /var/www/downloads/generator.php on line 33

Warning: readdir() expects parameter 1 to be resource, boolean given in /var/www/downloads/generator.php on line 34

Fatal error: Call to undefined function createPath() in /var/www/downloads/generator.php on line 36

Danach habe Ich die Variabel

PHP:
$path='.';
vor Line 33 eingefügt. Ergebnis:
Code:
Fatal error: Call to undefined function createPath() in /var/www/downloads/generator.php on line 36

Hab mir sogar noch deinen Wiki Eintrag http://wiki.yaslaw.info/wikka/PhpCreatePath reingezogen, aber trotzdem nicht schlüssig geworden.
zu SPiKEe's Lösung:

Bin noch dran den Befehl zu finden ;-) Resp. Im MySQL Administrator den Feldtyp zu definieren. Ich finde zwar die Lösung von Yaslaw eleganter und allenfalls besser um Erweiterungen zu definieren. Aber falls Ich dies nicht fertig bringen sollte bleibt mir keine andere Wahl...

So long, Gruss Patrick
 
Zuletzt bearbeitet:
oh, ja das mit dem Pfad ist aus meiner Testumgebung.
Kannste weglassen und so machen wie du es am Anfang hattest.

Es geht eigentlich nur um das erste SELECT und den geänderten Check-if().

@SPiKe
Jepp, kann an so machen. Aber nicht auf das einzelne Feld, da bei gleichem Dateiinhalt (zb. leere Datei) der md5-Wert derselbe ist.
Ich würde es auch über Error-Handling lösen. Wenn man da aber keine Erfahrung hat, sollte man zuerst die anderen Probleme lösen.
Im Gegensatz zu Java geht PHP gut ohne Errorhandling zum Programmieren (leider).
 
Zurück