PHP mail() - Dateigrößenbeschränkung für Attachment?

Hallo bplaced-Gemeinde,

ich bastle gerade an einem Formmailer. Bis auf einige kleinere Mängel funktioniert dieser technisch betrachtet auch schon recht anständig. Problematisch wird es jedoch, wenn der Besucher eine größere Datei im Anhang mitsenden möchte.

Laut meines E-Mail-Providers können Anhänge bis 20MB im System verarbeitet werden. Ein soeben gestarteter Versuch einen 10MB-Dateianhang von meinem E-Mail-Programm an mich selbst zu versenden und zu empfangen verlief tadellos. Versucht man nun aber die selbe Datei im Anhang des Formmailers zu versenden, verschwindet die komplette Nachricht im digitalen Datennirvana.

Woran liegt es nun, dass kleine Dateien versendet werden, größere hingegen aber nicht mehr? Gibt es bezüglich dieser Funktion Einschränkungen zu bestimmten Dateitypen und Dateigrößen? Falls ja, welche und wie hoch sind diese?

Gruß, Tobias

Hi,

PHP lässt hier nur max 2mb “arbeitsspeicher” oder wie man des auch immer nennen will zu

lg flo

Hej Ryon_,

Danke für die Antwort, aber das ist offenbar nicht der Schlüssel des Problems.

Hab es soeben mal mit 5,5MB Anhang versucht; Nachricht und Attachment sind fehlerfrei durchgegangen.

Gruß,
Tobias

Hallo bplaced,

könnte eventuell der Support weiterhelfen, ob Besonderheiten beim Attachment-Versand zu beachten sind?
Ich konnte erkennen, dass der Dateianhang vollständig zum Server übertragen wurde, aber von dort aus geht es offenbar nicht mehr weiter. Was könnte der Grund sein?

Freue mich über alles, was mich ein Stückchen schlauer macht,

Tobias

Hi

Bei php gibts ne Upload Dateigrössenbeschränkung…
Von einer bezüglich Anhängen weis ich nichts, von der Seite von PHP gibts da kaum was, aber ich weis nicht, wie hier die Mailserver (bzw. sendmail) konfiguriert sind / ist.

Obs an der Uploadbeschränkung liegt findest du hier heraus unter upload_max_filesize… Die scheint jedoch nicht das Problem zu sein (128M)

Hallo bcg,

vielen Dank für den aufschlussreichen Link - ich wusste bis dato gar nicht, dass man eine so detaillierte Aufstellung einfach aufrufen kann. Prima!

Nun, upload_file_size auf 128 MB und post_max_size auf 132 MB sind (insbesondere für Mail-Anhänge) mehr als ausreichend. Da wir hier über eine maximale Dateigröße von 20 MB sprechen, dürfte man diesen Punkt wohl ausschließen dürfen.

Weitere Informationen zum Thema ‘‘Konfigurationen für den Mailversand’’ fand ich soeben bei einem Mitbewerber unter http://www.isp-star.at/index.asp?file=php-upload-files.asp . Dort sind unter anderem auch die Einstellungen max_input_time und max_execution_time beschrieben.
Bei bplaced sind hierfür die Werte ‘‘20’’ und ‘‘12’’ eingetragen, aber um welch für eine Einheit handelt es sich hierbei? Sekunden??

Tobias

Sekunden, soweit ich weiß. Ob das aber damit was zu tun hat, keine Ahnung. Normal sollte hier bald mal einer vom Staff vorbeischaun :slight_smile:

Mfg :wink2:

Hallo,

Genau, dabei handelt es sich um Sekunden, siehe auch;
eass.bplaced.de/19-Technische-Informationen

Zum genauen Problem kann ich jetzt gerade nichts sagen, da es dieses Problem so in der Vergangenheit meines Wissens nicht gegeben hat. Ich werde aber hier mit miro Rücksprache halten und mich bei Zeiten wieder melden. :slight_smile:

Gruss

Hallo Mgier, hallo fusl,

danke für die weitere Klärung.

Ein Blick ins PHP-Handbuch besagt, dass die Standard-Einstellung für max_execution_time 30 Sekunden beträgt. bplaced liegt hier mit 12 Sekunden jedoch deutlich darunter.

Aus verschiedenen Foren konnte ich zudem erfahren, dass die Werte für max_input_time und max_execution_time gleiche Werte aufweisen sollten. Für einen reibungslosen Betrieb waren dort sogar 300 Sekunden empfohlen.

Wenn ich dies nun richtig interpretiere (berichtigt mich bitte, falls ich falsch liege) bedeutet das im vorliegenden Fall:
Nach Drücken des Submit-Buttons stehen exakt 20 Sekunden zur Verfügung, um die Nachricht samt Anhang zum Server zu senden, und 12 Sekunden für Nachricht und Anhang um selbigen wieder zu verlassen?

Tobias

Hallo

Wenn die Werte dort wirklich 300 (= 5 Minuten) sind, dann frag ich mich wozu das dienen soll (zumindest bei der execution_time) Schliesslich sollte ein Script möglichst schnell auszuführen sein. Der Benutzer wird eh nicht 5 Minuten auf eine Antwort vom Server warten.

Jain, ich weis nicht von wann an genau die 20 Sekunden gezählt werden, aber sicher frühstens von da an, wo die Verbindung beim Server ankommt (behaupt ich jetzt einfach mal so). Ich wusste nicht, dass die input_time bei Dateiuploads auch im Wege stehen kann (liegt wohl daran, dass ich bisher noch nie so grosse Dateien versendet habe) Wenn es daran liegen sollte, solltest du aber einen Fatal Error von PHP erhalten, der dich in englischer Sprache darüber informiert (das scheint aber nicht der Fall zu sein, da du nichts davon berichtet hast).

Das mit den 12 Sekunden stimmt nicht ganz. Dem Script stehen 12 Sekunden zur Verfügung, die Nachricht mit Anhang dem Mailserver (bzw. dem Sendmail-Script) zukommen zu lassen (da diese aber auf dem selber Server (Hardware) liegen, sollte das mehr als genug sein).

Anderer Ansatz (falls der Mailserver solche Anhänge nicht toleriert): Du könntest den Anhang als Datei (in einem geschützen Ordner) auf dem Webspace abspeichern und in der Mail einfach den Link dazu mitsenden.

Was du auch mal versuchen könntest: Reply-To und From Header in der Mail setzen, da dann eine Fehlermeldung vom Server an die dort angegebene Adresse gesendet werden müsste (wobei der From Header schon gesetzt sein müsste)…

Grüsse

Hi,

die max_input_time ist die Zeit, die der Server maximal nach dem erhalten aller Daten zeit hat um diese Daten zu parsen.
Die Zeit wird von dem Moment an gemessen, an dem alle Daten auf dem Server zur Verfügung stehen und mit dem parsen der Daten begonnen wird. (siehe php.net/manual/en/info.confi … input-time)

Hallo,

[quote]
Wenn die Werte dort wirklich 300 (= 5 Minuten) sind, dann frag ich mich wozu das dienen soll…[/quote]Der Grundgedanke (welcher zunächst auch meiner war) basiert offenbar auf der Annahme folgenden Beispiels:

[ul]Der Vorgang zum Versenden einer E-Mail incl. 6,4 MB Dateianhang dauert vom Drücken des Absende-Buttons bis zum Erscheinen der Bestätigungsseite (bei mir) ca. 2 Min. 15 Sek. [/ul]

Man sollte also meinen, dass max_input_time mit 300 Sek. eingestellt sein müsste, um den einwandfreien Empfang beim Server sicher zu stellen. Dass dem nicht so ist, hat freundlicherweise michi1234 widerlegt.

[quote]
Der Benutzer wird eh nicht 5 Minuten auf eine Antwort vom Server warten.[/quote]Das wird der Benutzer meiner Auffassung nach aber müssen. Die Idee, in der E-Mail einfach nur einen Link zum Anhang zu vermerken, ist durchaus eine Überlegung wert. Nichts desto trotz bleibt jedoch die Upload-Zeit. Mit einem netten Hinweis und eventuell einer Eier-Uhr lässt sich da aber bestimmt positiv entgegenwirken.

Um mehr Aufschluss über eventuell verborgene Fehlermeldungen zu erhalten habe ich heute mal unter http://www.foto-werk-stadt.bplaced.net/email_mit_dateianhang/formular.htm einen simplen 0/8/15-Formmailer mit folgenden Einstellungen ins Rennen geschickt:

$mailheader .= "Reply-To: " .$name. "<" .$email. ">\r\n"; $mailheader .= "Return-Path: tobias.hanke@XYZ.dk <tobias.hanke@XYZ.dk>\r\n"; $mailheader .= "Message-ID: <" .time(). " tobias.hanke@XYZ.dk>\r\n"; $mailheader .= "X-Mailer: PHP v" .phpversion(). "\r\n"; $mailheader .= "From: tobias.hanke@XYZ.dk <tobias.hanke@XYZ.dk>\r\n"; $mailheader .= "MIME-Version: 1.0\r\n"; $mailheader .= "Content-Type: multipart/mixed;\r\n"; $mailheader .= " boundary = " .$trenner; $mailheader .= "\r\n\r\n";mit welchen ich alle möglichen und unmöglichen Szenarien noch einmal durchgespielt habe.

Es ist vollkommen unerheblich, welche Empfänger-Adresse ich eintrage, oder mit welchem Browser ich das Skript aufrufe - das Ergebnis bleibt stets das selbe:

[ul]E-Mail mit 9,2 MB Anhang - Abbruch nach 2 Min. 58 Sek / weiße Seite / keine Fehlermeldungen
E-Mail mit 10,5 MB Anhang - Abbruch nach 3 Min. 37 Sek / weiße Seite / keine Fehlermeldungen[/ul]

Vielleicht möchte ja der ein oder andere von Euch das mal testen, ob ihr dasselbe Resultat erhaltet. Als Anhang sind jedoch nur *.jpg - Dateien zulässig. Bin echt gespannt wie’s nun weiter geht…

Freundliche Wochenendgrüße,

Tobias

[quote=“Foto-Werk-Stadt”]

[quote]
Wenn die Werte dort wirklich 300 (= 5 Minuten) sind, dann frag ich mich wozu das dienen soll…[/quote]Der Grundgedanke (welcher zunächst auch meiner war) basiert offenbar auf der Annahme folgenden Beispiels:

[ul]Der Vorgang zum Versenden einer E-Mail incl. 6,4 MB Dateianhang dauert vom Drücken des Absende-Buttons bis zum Erscheinen der Bestätigungsseite (bei mir) ca. 2 Min. 15 Sek. [/ul]

Man sollte also meinen, dass max_input_time mit 300 Sek. eingestellt sein müsste, um den einwandfreien Empfang beim Server sicher zu stellen.[/quote]
Ja, bei einem File Upload ist klar, dass da der Benutzer bei der ladezeit toleranter ist (zumindest kann man das hoffen :wink: ). Ich meinte damit eigentlich vorallem die execution_time …

[quote]Vielleicht möchte ja der ein oder andere von Euch das mal testen, ob ihr dasselbe Resultat erhaltet. Als Anhang sind jedoch nur *.jpg - Dateien zulässig. Bin echt gespannt wie’s nun weiter geht…[/quote] Vielleicht dürfen wir mal dein Script ansehen (also den PHP Code)?

Grüsse

Ich hatte gerade eine 10MB-Datei hochgeladen und dann per PHPMailer5.1 an GoogleApps versendet. Das hat funktioniert, angekommen sind jedoch nur etwa 1.5MB…

[quote]Vielleicht dürfen wir mal dein Script ansehen[/quote]Na aber gern doch :slight_smile: !
Also das Script, welches ich zum Testen hochgeladen habe, stammt von http://www.phpbuddy.eu/emails-mit-php-versenden.html?start=4 .
Alles in allem kommt es mit folgenden 4 Dateien aus:

  1. formular.htm (die Eingabemaske, über welche gestartet wird)

[code]

HTML Email mit Dateianhang Name:
Email:
Betreff:
Nachricht:
Anhang:
[/code] 2. funktionen.inc.php (zur Prüfung der Benutzer-Eingaben) [code]<?php

header( ‘Content-Type: text/html; charset=utf-8’ );

// Benutzereingabe bereinigen (trimmen, Slashes entfernen)
function cleanInput()
{
checkInjection();
if (get_magic_quotes_gpc()) $_POST = array_map( ‘stripslashes’, $_POST );
$_POST = array_map( ‘trim’, $_POST );
}

// Name auf Gültigkeit prüfen
function checkName( $name )
{
$muster_name = ‘/^([a-zA-ZäÄöÖüÜß\xc0-\xc2\xc8-\xcf\xd2-\xd4\xd9-\xdb\xe0-\xe2\xe8-\xef\xf2-\xf4\xf9-\xfb\x9f\xff.’-_]?(\s)?)+$/’;
if (preg_match( $muster_name, $name ))
{
return $name;
}
else
{
die( ‘Der eingegebene Name enthält nicht erlaubte Zeichen!’ );
}
}

// Email auf korrektes Format prüfen
function checkEmail( $email )
{
$nonascii = “\x80-\xff”;
$nqtext = “[^\\$nonascii\015\012”]";
$qchar = “\\[^$nonascii]”;
$normuser = ‘[a-zA-Z0-9][a-zA-Z0-9_.-]’;
$quotedstring = “”(?:$nqtext|$qchar)+"";
$user_part = “(?:$normuser|$quotedstring)”;
$dom_mainpart = '[a-zA-Z0-9][a-zA-Z0-9._-]
\.’;
$dom_subpart = ‘(?:[a-zA-Z0-9][a-zA-Z0-9._-]\.)’;
$dom_tldpart = ‘[a-zA-Z]{2,5}’;
$domain_part = “$dom_subpart$dom_mainpart$dom_tldpart”;
$pattern = “$user_part@$domain_part”;
$muster_email = “/^{$pattern}$/”;
if (preg_match( $muster_email, $email ))
{
return $email;
}
else
{
die( ‘Die eingegebene Email-Adresse hat kein gültiges Format!’ );
}
}

// Dateianhang prüfen
function checkFile()
{
if ($_FILES[‘datei’][‘error’] == 0 &&
$_FILES[‘datei’][‘type’] == ‘image/jpeg’)
{
return $_FILES[‘datei’][‘name’];
}
else
{
die( ‘Bitte eine gültige JPG Datei anhängen!’ );
}
}

// Benutzereingaben auf mögliche Injection prüfen
function checkInjection()
{
$email_injection = array( ‘bcc:’, ‘boundary’, ‘cc:’, ‘content-transfer-encoding:’, ‘content-type:’, ‘mime-version:’, ‘subject:’ );

// Auf potentielle Email Injections prüfen
foreach ($email_injection as $injection)
{
	foreach ($_POST as $feld => $inhalt)
	{
		if (preg_match( "/{$injection}/i", $inhalt ))
		{
			header( 'location: http://www.google.com/search?hl=en&q=how+to+become+a+better+hacker' );
			exit;
		}
	}
}
return true;

}

?>[/code]
3. mail.php (Der Mail-Header)

[code]<?php

header( ‘Content-Type: text/html; charset=utf-8’ );

// Empfänger Email
$empfaenger = ‘foto-werk-stadt@XYZ.dk’;

// Prüfen ob das Formular abgeschickt wurde
if (isset($_POST[‘senden’]) && $_FILES[‘datei’][‘size’] > 0)
{
// Funktionen einbinden
include( ‘funktionen.inc.php’ );

// Benutzereingaben bereinigen und auf Injection prüfen
cleanInput();

// Name prüfen
$name = checkName( $_POST['name'] );
// Email prüfen
$email = checkEmail( $_POST['email'] );
// Betreff und Nachricht prüfen
if ((strlen( $_POST['betreff'] ) < 5) || (strlen( $_POST['nachricht'] ) < 5))
{
	die( 'Bitte füllen Sie alle Felder aus!' );
}
else
{
	$betreff   = $_POST['betreff'];
	$nachricht = $_POST['nachricht'];
}
// Upload prüfen
$uploadname = checkFile();

// --------------------------------------------------------------------------------
// Wurde das Script bisher nicht abgebrochen, wurde das Formular korrekt ausgefüllt
// --------------------------------------------------------------------------------

// Template mit dem Mailbody laden
$template = file_get_contents( 'mailbody.txt' );
// Trenner für den Anhang
$trenner = md5( time() );

// Platzhalter mit den Benutzereingaben ersetzen
$template = str_replace( '###NAME###', htmlspecialchars( $name ), $template );
$template = str_replace( '###EMAIL###', $email, $template );
$template = str_replace( '###NACHRICHT###', nl2br( htmlspecialchars( $nachricht ) ), $template );

// Mail Header erstellen
$mailheader .= "Reply-To: " .$name. "<" .$email. ">\r\n";
$mailheader .= "Return-Path: tobias.hanke@XYZ.dk <tobias.hanke@XYZ.dk>\r\n";  // noreply@" .$_SERVER['SERVER_NAME']. "\r\n";
$mailheader .= "Message-ID: <" .time(). " tobias.hanke@XYZ.dk>\r\n";  // <" .time(). " noreply@" .$_SERVER['SERVER_NAME']. ">\r\n";
$mailheader .= "X-Mailer: PHP v" .phpversion(). "\r\n";
$mailheader .= "From: tobias.hanke@XYZ.dk <tobias.hanke@XYZ.dk>\r\n";   // noreply@" .$_SERVER['SERVER_NAME']. "\r\n";
$mailheader .= "MIME-Version: 1.0\r\n";
$mailheader .= "Content-Type: multipart/mixed;\r\n";
$mailheader .= " boundary = " .$trenner;
$mailheader .= "\r\n\r\n";

// Mailbody vorbereiten
$mailbody  = "This is a multi-part message in MIME format\r\n";
$mailbody .= "--" .$trenner. "\r\n";
$mailbody .= "Content-Type: text/html; charset=UTF-8\r\n";
$mailbody .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$mailbody .= $template. "\r\n\r\n";

// Anhang anfügen
$mailbody .= "--" .$trenner. "\r\n";
$mailbody .= "Content-Type: image/jpeg; name=\"" .$uploadname. "\"\r\n";
$mailbody .= "Content-Transfer-Encoding: base64\r\n";
$mailbody .= "Content-Disposition: attachment; filename=\"" .$uploadname. "\"\r\n\r\n";
$mailbody .= chunk_split( base64_encode( file_get_contents( $_FILES['datei']['tmp_name'] ) ) );
$mailbody .= "\n";

// Email versenden
if (@mail( $empfaenger, htmlspecialchars( $betreff ), $mailbody, $mailheader ))
{
	// Bei erfolgreichem Versand Danke-Seite anzeigen
	echo 'Danke, die Email wurde verschickt!';
}

}

?>[/code]
4. mailbody.txt (die html-Mail)

[code]

Email als HTML mit Anhang body { font: normal 12px Verdana, Arial, Helvetica, sans-serif; } a { color: blue; text-decoration: none; } h2 { font-size: 16px; font-weight: bold; } .gruen { color: green; }

Soeben ist eine Nachricht von ###NAME### eingetroffen.

Als Antwortadresse wurde ###EMAIL### angegeben.

Die Nachricht die gesendet wurde lautet:
###NACHRICHT###

[/code] Das Script ist funktionsfähig. Sämtliche verfügbaren Platzhalter habe ich gegen meinen E-Mailadressen ausgetauscht, ansonsten jedoch keine Änderungen vorgenommen. Wie bereits erwähnt, gehen aber auch mit diesem simplen Formmailer keine größeren Anhänge raus.

Gruß, Tobias