Zur Navigation

mail() in php7

1 AndiN

Hallo zusammen,
ich bin gerade dabei eine Website für PHP 7 flott zu machen (bisher lief PHP 5.2 auf dem Server). Ich habe auf der Website ein Formular, mit welchem man ein PDF-Dokument versenden kann (oder auch nicht). Bisher hat das wunderbar funktioniert. Nach der Umstellung bekomme ich folgende Fehlermeldung bei der Variante mit PDF-Anhang in der Zeile mit mail():

"Multiple or malformed newlines found in additional_header"

Der E-Mail-Versand ohne Datei-Anhang klappt wie bisher hervorragend.

Variante ohne Datei-Anhang
<?php
$body = "\nblabla\n";
$header = "";
$header = "From: ".$email;
mail($orderemail,$lang_agb." ".$firmenname,$body,$header);
?>

Variante mit Datei-Anhang
<?php
$agb_file = "files/agb.pdf";
$agb_name = "agb.pdf";
$agb_file_content = fread(fopen($agb_file,"r"),filesize($agb_file));
$agb_file_content = chunk_split(base64_encode($agb_file_content));
$boundary = strtoupper(md5(uniqid(time())));
$body = "\nblabla\n";

$header = "";
$header = "From: ".$email."\nMIME-Version: 1.0\nContent-Type: multipart/mixed; boundary=".$boundary."\n\nDies ist eine mehrteilige Nachricht im MIME-Format\n--".$boundary."\nContent-Type: text/plain\nContent-Transfer-Encoding: 8bit\n\n".$body;
$header.= "\n--$boundary";
$header.= "\nContent-Type: application/octetstream; name='agb_name'";
$header.= "\nContent-Transfer-Encoding: base64";
$header.= "\nContent-Disposition: attachment; filename='agb_name'";
$header.= "\nagb_file_content'}";
$header.= "\n--$boundary--";

mail($orderemail,$lang_agb." ".$firmenname,$body,$header);
?>

12.10.2016 17:47

2 Jörg Kruse

Um Header-Injection zu verhindern, können wohl nur noch wirkliche Header in dem vierten Argument (additonal_header, bei dir $header) untergebracht werden, keine Message mitsamt Anhängen mehr, die durch eine doppelte Newline angehangen werden.

Hier wird die Problematik auch behandelt:

http://stackoverflow.com/questions/30887610/error-with-php-mail-multiple-or-malformed-newlines-found-in-additional-header

In der zweiten Antwort ist auch beschrieben, wie man den Anhang in das dritte Argument (message, bei dir $body) verschiebt, welches ja die eigentliche Message beinhalten soll. Probier mal, ob das so für dich funktioniert

12.10.2016 18:07 | geändert: 12.10.2016 18:09

3 AndiN

Danke für den Link! Das hat schonmal sehr zum Verständnis beigetragen. Ich habe nun ein Script gefunden welches ich für mich angepasst habe. Mittlerweile klappt der E-Mail-Versand wieder, allerdings fehlen im E-Mail-Text die Zeilenumbrüche. Bei der Version ohne Datei-Anhänge bei der ich das Script auch nicht benutze ist alles gut. Ich bin aktuell am Suchen und Testen wo hier das Problem liegt. Fällt euch/dir evtl. etwas auf woran das liegen könnte?

function mail_att($to,$subject,$message,$attachments,$absender,$reply)
{
	$mime_boundary = "-----=" . md5(uniqid(mt_rand(), 1));

	$header  ="From:".$absender."<".$reply.">\n";
	$header .= "Reply-To: ".$reply."\n";
	$header.= "MIME-Version: 1.0\r\n";
	$header.= "Content-Type: multipart/mixed;\r\n";
	$header.= " boundary=\"".$mime_boundary."\"\r\n";

	$content = "This is a multi-part message in MIME format.\r\n\r\n";
	$content.= "--".$mime_boundary."\r\n";
	$content.= "Content-Type: text/html charset=\"iso-8859-1\"\r\n";
	$content.= "Content-Transfer-Encoding: 8bit\r\n\r\n";
	$content.= $message."\r\n";
 
	foreach($attachments AS $dat)
	{
		$data = chunk_split(base64_encode($dat['data']));
		$content.= "--".$mime_boundary."\r\n";
		$content.= "Content-Disposition: attachment;\r\n";
		$content.= "\tfilename=\"".$dat['name']."\";\r\n";
		$content.= "Content-Length: .".$dat['size'].";\r\n";
		$content.= "Content-Type: ".$dat['type']."; name=\"".$dat['name']."\"\r\n";
		$content.= "Content-Transfer-Encoding: base64\r\n\r\n";
		$content.= $data."\r\n";
	}
	$content .= "--".$mime_boundary."--"; 
	if(@mail($to, $subject, $content, $header))
		return true;
	else
		return false;
}
$body = "\n".html_entity_decode(strip_tags(str_replace("<br />"," \n ",$shop_email_text)))."\n";

$dateien = array();
$dateien[] = $agb_file;
$attachments = array();
foreach($dateien AS $datei)
{
	$name = basename($datei);
	$size = filesize($datei);
	$data = file_get_contents($datei);
	$type = mime_content_type($datei);
	$attachments[] = array("name"=>$name, "size"=>$size, "type"=>$type, "data"=>$data);
}
if($shoppdf != "")
	mail_att($shopemail,$lang_eingangsbestaetigung,$body,$attachments,$praxisname,$email);
else
{
	$header = "From: ".$email;
	mail($shopmail,$lang_eingangsbestaetigung." ".$praxisname,$body,$header);
}

17.10.2016 15:34

4 Jörg Kruse

	$content.= "Content-Type: text/html charset=\"iso-8859-1\"\r\n";

Also eine HTML-Mail

$body = "\n".html_entity_decode(strip_tags(str_replace("<br />"," \n ",$shop_email_text)))."\n";

Hier werden alle HTML-Breaks durch Newlines ersetzt und anschließend auch alle übrigen HTML-Tags entfernt. Dieses Vorgehen ist doch eher für eine Text-Mail geeignet? In der HTML-Ansicht fehlen dann die Umbrüche.

17.10.2016 15:48

5 AndiN

Das dachte ich auch schon, aber eine Änderung von

$body = "\n".html_entity_decode(strip_tags(str_replace("<br />"," \n ",$shop_email_text)))."\n";

auf

$body = "\n".$shop_email_text."\n";

hatte leider absolut keinen Effekt.


NACHTRAG:
Ich habe jetzt komplett auf den Content-Type "text/plain" umgestellt.
Jetzt geht's!

17.10.2016 16:00 | geändert: 17.10.2016 16:19

6 Jörg Kruse

Enthält $shop_email_text überhaupt HTML? wenn nicht, musst du mit nl2br noch Umbrüche einfügen; oder alternativ den Inhalt als "text/plain" kennzeichnen

Edit: ja, da war ich etwas zu spät ;)

17.10.2016 16:23 | geändert: 17.10.2016 16:23

1 Forenmitglied fand diesen Beitrag gut

Beitrag schreiben (als Gast)

Die Antwort wird nach der Überprüfung durch einen Moderator freigeschaltet.





[BBCode-Hilfe]