Zitat:
Original geschrieben von dommeliveaol
Hoffst du es, dass ich die alleine Zusammenkleben kann?^^
|
Yep.
Ist nicht sooo schwer.
Zitat:
Weil irgendwie habe ich nichtmals einen Anfang um ehrlich zu sein wenn ich mir das durchlese
|
Oweia, was wird dann erst, wenn du das Folgende durchliest?
Was du eigentlich willst, sind nicht zufällige sondern eindeutige Dateinamen.
PHP erledigt das Erzeugen eines eindeutigen Namens beim Dateipload schon für dich.
Ein erfolgreicher Beispiel-Upload.
Var_dump($_FILES) liefert in etwa Folgendes:
Code:
hash(1) {
['file'] => hash(5) {
['name'] => string(39) 'vom-browser-gesendeter-dateiname.jpg'
['type'] => string(8) 'image/jpeg'
['tmp_name'] => string(25) 'C:\blubb\Temp\php0815.tmp'
['error'] => integer() 0
['size'] => integer() 11503
}
}
Du siehst im Eintrag 'name' den Namen der hochgeladenen Datei, so wie sie der Browser gesendet hat.
Im Eintrag 'tmp_name' siehst du den eindeutigen Dateinamen für die hochgeladene Datei. Die befindet sich in einem bestimmten Verzeichnis, das PHP für alle temporären Dateien benutzt.
Aus beiden Bestandteilen kannst du nun einen eigenen Dateinamen zusammenbauen. Du brauchst vom 'name'-Feld die Endung und vom 'tmp_name'-Feld den Dateinamen ohne dessen '.tmp'-Endung.
Für letzteres hat PHP die Funktion basename():
PHP-Code:
// entfernt pfad und die Endung '.tmp':
$temp_basename = basename($_FILES['file']['tmp_name'], '.tmp')
Das Herauspulen der Endung habe ich anders gelöst:
PHP-Code:
$tag = preg_match('/\.[^.\/\x5c]+/', $_FILES['files']['name'], $hits)
? $hits[0] :
'';
Es wird das letzte Stück eines Dateipfades,
beginnend beim letzten gefundenen Punkt '.',
der von beliebigen Zeichen --
außer des Punktes '.', des Slashes '/' oder des Backslashes '\' --,
gefolgt werden darf,
herausgeschnitten.
Lies dir das so lange durch, bis du es kapiert hast.
Für den Fall, dass kein Punkt und somit keine Endung gefunden wurde, wird ein Leerstring zurückgegeben.
Beide Teile klebst du mit dem Punkt-Operator '.' zusammen. Den kennst du hoffentlich:
PHP-Code:
$mein_einzigartiger_dateiname = $temp_basename . $tag;
Und weil der Dateiname alleine nicht ausreicht, kann man gleich noch den Pfad zum endgültigen Uploadverzeichnis davorsetzen:
PHP-Code:
$upload_file_path = $endgueltiges_uploadverzeichnis .
DIRECTORY_SEPARATOR .
$mein_eindeutiger_dateiname;
Weiter unten ist das ein wenig komplizierter gelöst, weil das endgültige Uploadverzeichnis auch mit einem Verzeichnistrenner am Ende geliefert werden könnte.
Am besten packen wir den ganzen Kram in eine Funktion. Die nimmt zwei Argumente entgegen:
* Das erste ist das endgültige Uploadverzeichnis, also das Verzeichnis, wo die
hochgeladene Datei am Schluss hin soll.
* Das zweite ist die gleiche Zeichenkette, die du im Upload-Formular als
'name'-Attribute für das <input type="file" ... />-Tag eingetragen hast.
Die beiden Werte werden geprüft. Waren sie in Ordnung, wird der neue Dateiname zusammengebaut und
die hochgeladene Datei ins endgültige Upload-Verzeichnis verschoben.
Traten irgendwelche Fehler auf, gibt die Funktion FALSE zurück.
Ging alles gut, gibts ein TRUE.
PHP-Code:
/// create unique filename and move uploaded temp-file
/// return BOOL success
function file_upload_unique_name(
$upload_dir,
$fitfn = 'file' /// STR form>input>type>file>name attribute
) {
if (!isset($_FILES[$fitfn]['name'])) {
// keine Datei hochgeladen (oder anderer Upload-Fehler)
return FALSE;
}
// Das endgültige Upload-Verzeichnis sollte natürlich vorhanden sein
if (FALSE === $upload_dir = realpath($upload_dir)) {
// Upload-Verzeichnis existiert nicht oder ist kein Verzeichnis
return FALSE;
}
// falls ein Upload-Fehler aufgetreten ist, beenden wir hier
if ($_FILES[$fitfn]['error']) {
return FALSE;
}
// die Dateiendung holen, sofern eine existiert
$tag = preg_match('/\.[^.\/\x5c]+/', $_FILES[$fitfn]['name'], $hits) ? $hits[0] : '';
// vom temporären Upload-Pfad
// den Dateinamen extrahieren und die Endung '.tmp' entfernen,
// die Endung $tag dahinter-
// und den Pfad zum Uploadverzeichnis davorkleben
$dst_path = preg_replace('/[\/\x5c]\z/', '', $upload_dir) .
DIRECTORY_SEPARATOR .
basename($_FILES[$fitfn]['tmp_name'], '.tmp') .
$tag;
return move_uploaded_file($_FILES[$fitfn]['tmp_name'], $dst_path);
}
Beim
Dateiupload treten manchmal Fehler auf. Die Fehlernummern allein sind nicht wirklich aussagekräftig. Also bauen wir uns eine Funktion, die entsprechenden Fehlermeldungen im (englischen) Klartext zurückgibt:
PHP-Code:
/// get error description for given uploaded file
/// return STR
function file_upload_error_description(
$fitfn = 'file' /// STR form>input>type>file>name attribute
) {
static $errors = array (
0 => 'There is no error, the file uploaded with success.',
1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive '.
'that was specified in the HTML form.',
3 => 'The uploaded file was only partially uploaded.',
4 => 'No file was uploaded.',
6 => 'Missing a temporary folder.', // Introduced in PHP 4.3.10 and PHP 5.0.3.
7 => 'Failed to write file to disk.', // Introduced in PHP 5.1.0.
8 => 'File upload stopped by extension.', // Introduced in PHP 5.2.0.
);
if (!isset($_FILES[$fitfn])) {
return 'There is no uploaded file "' . $fitfn . '"';
}
if (!isset($errors[$_FILES[$fitfn]['error']])) {
return 'Unknown error during file upload';
}
return $errors[$_FILES[$fitfn]['error']];
}
Und mit einem lustigen Affenformular testen wir das Ganze:
PHP-Code:
<?php
$upload_dir = 'f:/'; // destination directory for uploaded files
$fitfn = 'file'; // name attribute given for the input-(type=file)-element
$max_file_size = 5555; // max. upload file size in bytes
if (FALSE === $success = file_upload_unique_name($upload_dir, $fitfn)) {
echo file_upload_error_description($fitfn));
die('Fehler beim Dateiupload oder keine Datei hochgeladen!');
}
?>
<form action="" method="post" enctype="multipart/form-data">
<input type="xhidden" name="MAX_FILE_SIZE" value="<?php echo($max_file_size); ?>" />
<input type="file" name="<?php echo($fitfn); ?>" size="20" maxlength="<?php echo($max_file_size); ?>" accept="text/html">
<hr />
<input type="submit" />
</form>
?>