• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Upload Formular - Bilddatei überprüfen - Was läuft hier falsch?

Kirschtomate

New member
Hallo,

ich bastel schon seit einiger Zeit an einem HTML Upload Formular für Bilder. Dazu habe ich eine kleine Funktion geschrieben, mit welcher die Bildateien überprüft werden sollen.

PHP:
	function pic_upload($file_tmp_name, $file_size) {
		$var = '';
		$info = '';
		if($file_size == 0) {
			$var = false;
			$info = 'Es wurde kein Bild ausgewählt!';
		} else {
			$size = GetImageSize($file_tmp_name);
			if ($size[2] !== 2) {
				$var = false;
				$info = 'Es können nur .jpg Dateien hochgeladen werden!';
			} else {
				if ($file_size > 1024000) {
					$var = false;
					$info = 'Die maximal erlaubte Bildgröße ist 1MB!';
				} else {
					if ($size[0] < 900 || $size[1] < 600) {
						$var = false;
						$info = 'Die Mindestauflösung beträgt 900x600 Pixel!';
					}
				}
			}
		}
		return array($var, $info);
	}

	$pic = pic_upload($_FILES['pic']['tmp_name'], $_FILES['pic']['size']);

Allerdings habe ich ein seltsames Problem. Lade ich ein Testbild (.jpg) mit mit 1,14MB hoch erhalte ich die Meldung "Die maximal erlaubte Bildgröße ist 1MB!". Bei einer anderen Testdatei (ebenfalls .jpg) mit 3,8MB lautet die Meldung allerdings "Es wurde kein Bild ausgewählt!". Wie ist sowas möglich?
 
Guter Einwand, ich habe die Funktion nun umgeschrieben:

PHP:
function pic_upload($file_error, $file_tmp_name, $file_size) {
		$var = ''; $info = '';
		if ($file_error !== 0) {
			switch ($file_error) {
				case 1: $var = false; $info = 'Die maximal erlaubte Bildgröße ist 1MB!'; break;
				case 2: $var = false; $info = 'Die maximal erlaubte Bildgröße ist 1MB!'; break;
				case 3: $var = false; $info = 'Upload unvollständig!'; break;
				case 4: $var = false; $info = 'Es wurde kein Bild ausgewählt!'; break;
			}
		} else {
			$size = GetImageSize($file_tmp_name);
			if ($size[2] !== 2) {
				$var = false;
				$info = 'Es können nur .jpg Dateien hochgeladen werden!';
			} else {
				if ($file_size > 1024000) {
					$var = false;
					$info = 'Die maximal erlaubte Bildgröße ist 1MB!';
				} else {
					if ($size[0] < 900 || $size[1] < 600) {
						$var = false;
						$info = 'Die Mindestauflösung beträgt 900x600 Pixel!';
					}
				}
			}
		}
		return array($var, $info);
	}

	$pic = pic_upload($_FILES['pic']['error'], $_FILES['pic']['tmp_name'], $_FILES['pic']['size']);

Sieht zwar etwas verwirrend aus, aber besser kann ich es nicht. Für $_FILES['bild']['size'] wird "0" übertragen, wenn die maximale Größe überschritten wird, das macht es etwas knifflig.

Edit: Ich würde gerne bis maximal 4 Bilder auf einmal mit meinem Uploadformular hochladen können (wobei zumindest ein Bild hochgeladen werden muss). Anscheinend bietet sich dafür <input type="file" name="pic[]"> an. Lässt sich meine Funktion umschreiben, dass sie Array tauglich ist?
 
Zuletzt bearbeitet:
Über das Phänomen bin ich auch schon gestolpert, mein Workaround sieht so aus: error != 4 (4=keine datei hochgeladen) && size == 0 => datei zu groß (gleicher fehler triggert wie error = 1)
 
Sehr aufmkersam, danke für den Post. Ich habe mein Formular nun auf "Array" umgestellt. "Value" Eingaben wie bei Checkboxen sind anscheinend nicht erforderlich.

PHP:
<form enctype="multipart/form-data" method="post" action="process.php">
	<input type="hidden" name="MAX_FILE_SIZE" value="1024000">
	<input type="file" name="pic[]" size="25"><br />
	<input type="file" name="pic[]" size="25"><br />
	<input type="file" name="pic[]" size="25"><br />
	<input type="submit" value="Send!">
</form>

Mit Arrays unf foreach Schleifen kenn ich mich leider noch nicht so richtig aus. Diese einfache Fehlerprüfung funktioniert allerdings bereits. Da sie aber bei mehreren Überschreitungen der Dateigröße mehrmals den gleichen Fehler ausgibt, ist sie nicht besonders praxistauglich.

PHP:
$error = $_FILES['pic']['error'];
	
foreach ($error as $single_error) {
	if ($single_error == 1 || $single_error == 2) {
		echo 'Datei zu groß!<br />';
	}

Folgende Fehlerprüfung funktioniert leider nicht. Kann mir jemand einen Tipp geben, was ich anders machen muss?

PHP:
foreach ($_FILES as $single_file) {
	if ($single_file['error'] == 1 || $single_file['error'] == 2 || $single_file['size'] > 1024000) {
			echo ' Die Datei ' . $single_file['name'] . ' ist zu groß!<br />';
	}
}
 
Zuletzt bearbeitet:
Ich habe mein Problem nun so gelöst:

PHP:
$upload_error = 'y';

// Mindestens ein Bild
foreach ($_FILES as $single_file) {
	foreach ($single_file['error'] as $error) {
		if ($error !== 4) { $upload_error = 'n'; }
	}
}
	
// Nur JPG Dateien (Mindestauflösung 900x600 Pixel)
foreach ($_FILES as $single_file) {
	foreach ($single_file['tmp_name'] as $tmp_name){
		if (!empty($tmp_name)) {
			$image_size = GetImageSize($tmp_name);
			if ($image_size[2] !== 2 || $image_size[0] < 900 || $image_size[1] < 600) { $upload_error = 'y'; }
		}
	}
}
	
// Bildgröße maximal 1MB
if ($upload_error !== 'y') {
	foreach ($_FILES as $single_file) {
		foreach($single_file['error'] as $error){ 
			if ($error == 1 || $error == 2) { $upload_error = 'y'; } 
		} 
		foreach ($single_file['size'] as $size) { 
			if ($size > 1024000) { $upload_error = 'y'; } 
		}    
	}
}
	
if ($upload_error == 'y') {
	echo 'Fehler: Nur JPG Dateien (min. 600x900 Pixel, max. 1MB) sind erlaubt! Es muss mindestens eine Datei ausgewählt werden!';
	exit();
}

Ich bitte um einen Kommentar, ob das eine gute Lösung ist.
 
Zuletzt bearbeitet:
Darauf hätte ich eigentlich auch selbst kommen können ...zumindest mit etwas zeitlichem Abstand. Also nochmal:

PHP:
$upload_check = false;
   
// Mindestens ein Bild
foreach ($_FILES['pic']['error'] as $error) { 
	if ($error !== 4) { $upload_check = true; } 
}

// Dateigröße maximal 1MB
// upload_max_filesize (php.ini) und MAX_FILE_SIZE (HTML form)
if ($upload_check == true) { 
	foreach ($_FILES['pic']['error'] as $error) {  
		if ($error == 1 || $error == 2) { $upload_check = false; }  
	} 
}
	
// Nur JPG Dateien (Mindestauflösung 900x600 Pixel) 
foreach ($_FILES['pic']['tmp_name'] as $tmp_name) { 
        if (!empty($tmp_name)) { 
            $image_size = GetImageSize($tmp_name); 
            if ($image_size[2] !== 2 || $image_size[0] < 900 || $image_size[1] < 600) { $upload_check = false; } 
        } 
   } 
		
// Dateigröße maximal 1MB
// Nur wenn nicht bereits zuvor gescheitert
if ($upload_check == true) { 
	foreach ($_FILES['pic']['size'] as $size) {  
		if ($size > 1024000) { $upload_check = false; }  
	}
}
	
switch ($upload_check) {
	case true: echo 'OK! '; break;
	case false: echo 'Fehler: Nur JPG Dateien (min. 600x900 Pixel, max. 1MB) sind erlaubt! Es muss mindestens eine Datei ausgewählt werden!!';  exit(); break;
}

Zum Schluss werden die Bilder noch per Mail versandt (PHP Mailer). Ich habe mich an Bsp. 3 des PHP-Manual Links orientiert.

PHP:
foreach ($_FILES['pic']['tmp_name'] as $key => $tmp_name) {
	$name = $_FILES['pic']['name'][$key];
	if (!empty($tmp_name)) {
		$mail->AddAttachment($tmp_name, $name);
	}
}

Edit: Allerdings verstehe ich nicht warum z.B. eine 4MB .jpg Datei eine halbe Ewigkeit an den Server übermittelt wird, bevor ich meine Fehlermeldung erhalte. (Auch wenn ich meine "Nur JPG Dateien" Prüfung in eine "if ($upload_check == true)" Schleife stecke.)
 
Zuletzt bearbeitet:
Moin
Diese zwei Blcke hier
PHP:
// Mindestens ein Bild
foreach ($_FILES['pic']['error'] as $error) { 
    if ($error !== 4) { $upload_check = true; } 
}

// Dateigröße maximal 1MB
// upload_max_filesize (php.ini) und MAX_FILE_SIZE (HTML form)
if ($upload_check == true) { 
    foreach ($_FILES['pic']['error'] as $error) {  
        if ($error == 1 || $error == 2) { $upload_check = false; }  
    } 
}
kannst du doch einfach zu folgendem
PHP:
// Mindestens ein Bild
// Dateigröße maximal 1MB
// upload_max_filesize (php.ini) und MAX_FILE_SIZE (HTML form)
foreach ($_FILES['pic']['error'] as $error) { 
    if ($error !== 1 || $error == !2 || $error !== 4) {
        $upload_check = true;
    } else {
        $upload_check = false;
    }
}
zusammenfassen oder?

Generell könntest du doch deine Abfrage weiter zusammenfassen.
Immerhin durchforstest du dauernd das $_FILES['pic']
Muss das unbedingt mit foreach pasieren? Mit einem einfachen if...else if...else Konstrukt müsste das doch einfacher sein.
Oder wenn dann eine ausgeklügeltere foreach...
 
zusammenfassen oder?

Nein, funktioniert leider nicht. In meiner Version wird "$upload_check" im ersten Block auf "true" gesetzt, sobald eine Datei ausgewählt wurde. Bei deiner Version, wird "$upload_check" auch auf "true" gesetzt, wenn keine Datei gewählt wurde. Schade, optisch gefällt mir dein Code besser :)

Zum Edit: die 4MB werden trotzdem übertragen. Das dauert hald seine Zeit.

Ich dachte wenn "$error" den Wert "2" (MAX_FILE_SIZE) entspricht, wird die Datei nicht hochgeladen (sofern der Code im Skript dementsprechend gestaltet ist).
 
Zuletzt bearbeitet:
Aus den || (oder) müssen && (und) werden... dann sollte auch der Code von miniA4kuser funktionieren.

Ich denke nicht, dass $error der Wert 2 hat, sondern 1 - soweit ich weiß, ignorieren alle Browser MAX_FILE_SIZE in einem Formular.
 
Zurück
Oben