Dateien in php umbenennen
Voku Hila
- php
Hallo,
ich habe 3 Dateien pro Verzeichnis.
Nach dem Durchlauf der Datei nur noch eine.
Warum?
function get_dir ($dir) {
$fp=opendir($dir);
while($datei=readdir($fp)) {
if ($datei!="." && $datei!="..") {
// wenn datei, dann umbenennen
if (is_dir($dir."/".$datei)) {
echo "---> ".$dir."/".$datei." <br/><br/>";
} else {
$datei_neu = uniqid().".jpg";
rename($dir."/".$datei, $dir."/".$datei_neu);
echo $dir."/".$datei." <br/>";
}
}
if (is_dir($dir."/".$datei) && $datei!="." && $datei!=".."){
get_dir($dir."/".$datei);
}
}
closedir($fp);
}
get_dir("C:/vergleiche");
Voku
Nach dem Durchlauf der Datei nur noch eine.
Warum?
Gefunden.
$datei_neu = md5(uniqid(mt_rand(), true)).".jpg";
Hallo Voku Hila,
ich habe deine „Lösung“ mit -1 markiert, weil sie das Problem mit Brachialgewalt erschlägt, nach dem Motto: Irgendwas wird schon helfen.
Grundproblem ist: uniqid() basiert intern auf dem aktuellen microtime() Wert. Ein schnell laufendes Programm auf einem schnellen Server ist durchaus im Stande, in einer einzigen Mikrosekunde diese Funktion mehrfach aufzurufen - trotz Dateioperationen (die werden vom Betriebssystem ohnehin im Cache ausgeführt).
Ich habe keinen Überblick über die Codeentwicklung von PHP, es gibt aber Versionen von uniqid die usleep() aufrufen, und damit bis zu 10ms Verzögerung produzieren, andere machen einen active wait, bis sich der microtime-Wert seit dem letzten Aufruf ändert, und es gibt auch welche, die machen gar nichts und können damit tatsächlich gleiche Werte produzieren.
Deswegen gibt es die beiden Ergänzungsparameter. Der erste dient dazu, bei parallel laufenden Systemen (Thread, Prozess, Maschine) der uniqid ein Präfix voranzustellen, das den Parallelzweig identifiziert und damit verhindert, dass zwei parallele Zweige die gleiche ID produzieren. Der zweite generiert eine Zufallszahl und hängt sie an die erzeugte ID an.
Dein Code produziert per Mersenne-Twister eine Zufallszahl als Präfix, dann kommt der microtime-basierende uniqid-Wert und schließlich eine weitere Zufallszahl, diesmal per doppeltem Kongruenzgenerator.
Das jagst du dann durch md5() - vermutlich um schön gleich lange Dateinamen zu bekommen. In zwei Monaten versteht das kein Mensch mehr.
Statt dieses Aufwandes kannst Du Dir einmal per microtime(true) die aktuelle Zeit holen, diesen Wert speichern, pro rename um 1 hochzählen und dem md5 Hash des Zählerstandes bestimmen. Oder einfach einen int-Zähler hochdrehen, die Zahl in einen String umwandeln und den als Dateiname nutzen. Der Zähler muss natürlich global sein, sonst klappt die Rekursion nicht.
Rolf
@Rolf: Das Script solte 1 x durchlaufen jund danach in der ewigen versenkung verschwinden. Es ging darum, 10 Ordner mit Vergleichsphotos namentlich so zu beeinflussen, dass man nicht anhand der Dateinamen die Kamera erahnen kann, die das Photo gemacht hat.
Dann nim doch einfach md5 oder sha1 vom Dateinamen, oder gibt es die Befürchtung, dass das jemand zurückrechnen will?
Hello,
das ist wohl nicht das Hauptproblem, sondern die verwendung det File(opem)modes.
Da gibt es ja Strategien.
Wenn ich wieder auf Desktop bin, schreibe ich noch ezwas darüber.
Liebe Grüße
Tom S.
Dann nim doch einfach md5 oder sha1 vom Dateinamen
Wenn es nicht auf Performance ankommt, dann könnte man bei einer vergleichbaren Anwendung sogar den Hash des Dateiinhalts nehmen und hätte am Ende wenigstens keine "binär identischen" Bilder …
Beispielhafte Anwendung:
$newFileName = $newDir . '/' . md5( file_get_contents( $oldFileName ) ) . '.jpg';
if ( ! is_file($newFileName ) ) {
if ( copy( $oldFileName, $newFileName ) ) {
echo "Erfolg: Die Datei '$oldFileName' wurde nach '$newFileName' kopiert.", PHP_EOL );
} else {
echo ( "Fatal: Die Datei '$oldFileName' konnte nicht nach '$newFileName' kopiert werden.", PHP_EOL );
}
} else {
echo ( "Notiz: Die Datei '$oldFileName' wurde nicht kopiert, weil sie eine Kopie von '$newFileName' ist.", PHP_EOL );
}