i have an upload script with that i like to upload a couple of images to a directory.
i use this code:
$allowed_extension = array('jpg', 'jpeg', 'png', 'bmp', 'tiff', 'gif');
$errors = array();
$output = array();
if(!empty($_FILES['image']['tmp_name'])){
foreach($_FILES['image']['name'] as $key => $array_value){
if(!in_array(pathinfo($_FILES['image']['name'][$key], PATHINFO_EXTENSION), $allowed_extension)){
die("Die!");
}
}
foreach($_FILES['image']['name'] as $key => $array_value){
$file_name = $_FILES['image']['name'][$key];
$file_size = $_FILES['image']['size'][$key];
$file_tmp = $_FILES['image']['tmp_name'][$key];
$file_extension = pathinfo($file_name, PATHINFO_EXTENSION);
$file_extension = strtolower($file_extension);
if (!in_array($file_extension, $allowed_extension)){
$errors[$file_name][] = "format $file_extension in image $file_name is not accepted";
continue;
}
if ($file_size > 2097152){
$errors[$file_name][] = "maxsize of 2MB on $file_name has reached";
}
if (count($errors) == 0){
$dir = "a/b/c";
if (is_dir($dir)){
mkdir("a/b/c/tmp_images", 0755);
}else{
mkdir("a/b/c", 0755);
mkdir("a/b/c/tmp_images", 0755);
}
$path = "a/b/c/tmp_images";
$prifix = basename($file_name, "." . $file_extension);
//var_dump ($prifix);
$uploadfile = $path . "/" . $file_name;
$x = 0;
while (file_exists($uploadfile)){
$x ++;
$uploadfile = "{$path}/{$prifix}-{$x}.{$file_extension}";
}
if (move_uploaded_file($file_tmp, $uploadfile)){
$file_name = basename($uploadfile);
$output [$file_name] = "OK";
}else{
$output[$file_name] = "Failure while Uploading!";
$errors[$file_name][] = "Failure: Can't move uploaded pictures!";
}//else...
}//if(count($errors))...
}//foreach($_FILES['image']['name']...
}//if(!empty($_FILES['image']['tmp_name'])...
the problem is that part:
if(!empty($_FILES['image']['tmp_name'])){
foreach($_FILES['image']['name'] as $key => $array_value){
if(!in_array(pathinfo($_FILES['image']['name'][$key], PATHINFO_EXTENSION), $allowed_extension)){
die("Die!");
}
}
in case of uploading two different kind of file types it will cancel the upload. this is my first problem. in such a case i need to cancel the upload because this is for a file that i like to build after posting the form. so the user has no possibility to make any changes after he has post the form. let's have a look at the second part:
foreach($_FILES['image']['name'] as $key => $array_value){
$file_name = $_FILES['image']['name'][$key];
$file_size = $_FILES['image']['size'][$key];
$file_tmp = $_FILES['image']['tmp_name'][$key];
$file_extension = pathinfo($file_name, PATHINFO_EXTENSION);
$file_extension = strtolower($file_extension);
if (!in_array($file_extension, $allowed_extension)){
$errors[$file_name][] = "format $file_extension in image $file_name is not accepted";
continue;
}
if ($file_size > 2097152){
$errors[$file_name][] = "maxsize of 2MB on $file_name has reached";
...}
here it can be seen that it actually should be approached that an error message should have been displayed. if i leave the first foreach-part then i got the problem that in case of two different file types one file will be uploaded and for the other one the errormessage will be displayed.
so there should be a way to combine the first and the second foreach. if there is someone who could tell me the right way i really would appreciate. thanks a lot.
UPDATE
okay, sorry for my lateness. here my feedback: this code seems to have some problems in case of two different file types. it seems like
if (count($errors)>0){
die ("...")
}
does not really count. in case of that it will get the error message:
Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to access a/b/c/tmp_images/abc.xls
but it will also do an upload for the image that has an allowed extension but this can't be successfull because of the wrong filetype of the other one, i guess. the problem is that this causes the insert query that is placed here:
if (move_uploaded_file($fileTmp, $fileDst)) {
$output[$fileBase] = "OK";
**$insert = $db->query("INSERT INTO table ( a, b, c) VALUES('".$a."','".$b."','".$c."')");{
mkdir("a/b/c/d/e", 0755);
rename("a/b/c/tmp_images", "a/b/c/d/e/tmp_images");
$msg ="text abc.";
$to = "xxx@xxx.xx";
$subject = "xxx ";
$message = "text";
$headers = "From: xxx<xxx@xxx.xx>\r\n";
$headers .= "Content-type: text/plain; charset=UTF-8\r\n";
$mailheader .= "Return-Path: failuremail@" .$_SERVER['SERVER_NAME']. "\r\n";
$mailheader .= "MIME-Version: 1.0\r\n";
$mailheader .= "Content-Transfer-Encoding: 7bit\r\n";
$mailheader .= "Message-ID: <" .time(). " noreply@" .$_SERVER['SERVER_NAME']. ">\r\n";
$mailheader .= "X-Mailer: PHP v" .phpversion(). "\r\n\r\n";
mail($to, $subject, $message, $headers);
}//**
}else{
$output[$fileBase] = "Fehler beim Upload des Bildmaterials!";
$errors2[$fileBase][] = "Fehler: Die hochgeladenen Dateien können nicht verschoben werden!";
}//
}//
if (count($errors) > 0) {
die("Failurecode: ");
echo "$errors";
}...
and i would like to approach to get the error messages from the 2 dimensional array the same way like i get them from my other error messages that comes from one dimensional arrays at the same page as the formular will be. in case of "die" it will open a new empty page to show the error. thanks a lot.
You will need two loops for this, but the approach you have taken is slightly flawed. You need a validation loop which performs all the validation for all the files, then a second loop which just moves the files to permanent storage.
Something like this (FIXED):
<?php
// Settings
$allowedExtensions = array('jpg', 'jpeg', 'png', 'bmp', 'tiff', 'gif');
$maxSize = 2097152;
$storageDir = 'a/b/c/tmp_images';
// Result arrays
$errors = $output = array();
if (!empty($_FILES['image'])){
// Validation loop (I prefer for loops for this specific task)
for ($i = 0; isset($_FILES['image']['name'][$i]); $i++) {
$fileName = $_FILES['image']['name'][$i];
$fileSize = $_FILES['image']['size'][$i];
$fileErr = $_FILES['image']['error'][$i];
$fileExt = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
// Validate extension
if (!in_array($fileExt, $allowedExtensions)) {
$errors[$fileName][] = "Format $fileExt in image $fileName is not accepted";
}
// Validate size
if ($fileSize > $maxSize) {
$errors[$fileName][] = "$fileName excedes the maximum file size of $maxSize bytes";
}
// Check errors
if ($fileErr) {
$errors[$fileName][] = "$fileName uploaded with error code $fileErr";
}
}
// Handle validation errors here
if (count($errors) > 0) {
die("Errors validating uploads: ".print_r($errors, TRUE));
}
// Create the storage directory if it doesn't exist
if (!is_dir($storageDir)) {
if (!mkdir($storageDir, 0755, TRUE)) { // Passing TRUE as the third argument creates recursively
die("Unable to create storage directory $storageDir");
}
}
// File move loop
for ($i = 0; isset($_FILES['image']['name'][$i]); $i++) {
// Get base info
$fileBase = basename($_FILES['image']['name'][$i]);
$fileName = pathinfo($fileBase, PATHINFO_FILENAME);
$fileExt = pathinfo($fileBase, PATHINFO_EXTENSION);
$fileTmp = $_FILES['image']['tmp_name'][$i];
// Construct destination path
$fileDst = $storageDir.'/'.basename($_FILES['image']['name'][$i]);
for ($j = 0; file_exists($fileDst); $j++) {
$fileDst = "$storageDir/$fileName-$j.$fileExt";
}
// Move the file
if (move_uploaded_file($fileTmp, $fileDst)) {
$output[$fileBase] = "Stored $fileBase OK";
} else {
$output[$fileBase] = "Failure while uploading $fileBase!";
$errors[$fileBase][] = "Failure: Can't move uploaded file $fileBase!";
}
}
// Handle file move errors here
if (count($errors) > 0) {
die("Errors moving uploaded files: ".print_r($errors, TRUE));
}
}