0

I'm trying to send emails with attachment from a HTML form using PHP mail().

I have found a script online that works - but with one problem:

If a file is attached to the email, the script works fine. However, if there is no attachment, the email is sent but doesn't contain any text content (blank email body).

I want the ability to add an attachment to be optional.

My question is, how can an email be sent successfully, with or without an attachment?

Thanks!

The PHP script I'm using is as follows:

<?php

$email =  trim($_POST['email']);
$email_san = filter_var($email, FILTER_SANITIZE_EMAIL);

$fname = $_POST['first_name'];
$fname_san = filter_var($fname,FILTER_SANITIZE_STRING);

$lname = $_POST['last_name'];
$lname_san = filter_var($lname,FILTER_SANITIZE_STRING);

$org =  trim($_POST['organisation']);
$org_san =  filter_var($org,FILTER_SANITIZE_STRING);

$user_phone = $_POST['phone'];
$trim_phone = trim($user_phone);  
$replace_phone = preg_replace('/[^0-9+-]/', '', $trim_phone);
$phone_san = filter_var($replace_phone,FILTER_SANITIZE_NUMBER_INT);

$message = $_POST['message'];
$fromemail =  $email_san;
$subject="Inquiry";
$email_message = '<p><b>First Name:</b> '.$fname_san.'</p>
                <p><b>Organisation:</b> '.$org_san.'</p>
                <p><b>Email:</b> '.$email_san.'</p> 
                <p><b>Phone:</b> '.$phone_san.'</p>                    
                <p><b>Message:</b><br/>'.$message.'</p>';

$semi_rand = md5(uniqid(time()));
$headers = "From: ".$fromemail;
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";

$headers .= "\nMIME-Version: 1.0\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";

if($_FILES["file"]["name"]!= ""){  
$strFilesName = $_FILES["file"]["name"];  
$strContent = chunk_split(base64_encode(file_get_contents($_FILES["file"]["tmp_name"])));  


$email_message .= "This is a multi-part message in MIME format.\n\n" .
"--{$mime_boundary}\n" .
"Content-Type:text/html; charset=\"iso-8859-1\"\n" .
"Content-Transfer-Encoding: 7bit\n\n" .
$email_message .= "\n\n";


$email_message .= "--{$mime_boundary}\n" .
"Content-Type: application/octet-stream;\n" .
" name=\"{$strFilesName}\"\n" .
//"Content-Disposition: attachment;\n" .
//" filename=\"{$fileatt_name}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$strContent  .= "\n\n" .
"--{$mime_boundary}--\n";
}
$toemail="email@somedomain.com"; 

if(mail($toemail, $subject, $email_message, $headers)){
echo "Email sent.";
}else{

echo "Email NOT sent.";
}

?>

/*** UPDATE ***/

OK, taking advice that PHPMailer is a better method of sending emails, I have made another attempt to setup PHPMailer.

I don't have Composer so I downloaded and installed PHPMailer manually. I don't have Composer so I downloaded and installed PHPMailer manually. My server folder hierarchy is shown in this image.

I found a PHPMailer tutorial online which provided a simple script which I saved as 'mailer-test.php', uploaded and linked to my PHPMailer install:

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require_once "php-mailer/src/Exception.php";

//PHPMailer Object
$mail = new PHPMailer(true); //Argument 'true' in enables exceptions

//From email address and name
$mail->From = "me@mydomain.com";
$mail->FromName = "Full Name";

//To address and name
//$mail->addAddress("recipient@somedomain.com", "Recepient Name");
$mail->addAddress("recipient@somedomain.com"); //Recipient name is optional

//Address to which recipient will reply
$mail->addReplyTo("me@mydomain.com", "Reply");

//Send HTML or Plain Text email
$mail->isHTML(true);

$mail->Subject = "Subject Text";
$mail->Body = "<i>Mail body in HTML</i>";
$mail->AltBody = "This is the plain text version of the email content";

try {
    $mail->send();
    echo "Message has been sent successfully";
} catch (Exception $e) {
    echo "Mailer Error: " . $mail->ErrorInfo;
}

?>

However, when I view 'mailer-test.php' in a browser, I get the follwing server error:

This page isn't working. yourdomain.com is currently unable to handle this request. HTTP ERROR

What is causing this?

Ben
  • 5
  • 2
  • 6
  • Out of curiosity: is there any good reason to write all that stuff by hand? There are tons of good libraries out there (like PHPMailer, SwiftMailer) which would make you life much easier :) – Nico Haase Oct 09 '20 at 07:46
  • Tried PHPMailer but could not configure it. Wasted a day on this. At least this script works sometimes. – Ben Oct 09 '20 at 07:54
  • The question has changed / evolved. It was originally 'I want attachments to be optional, and I can't send an email without an attachment', and it now seems to be 'I'm getting an error sending an email after making code changes'. The etiquette is to raise a separate question (https://meta.stackoverflow.com/a/252129/3080207) – mikey Oct 12 '20 at 02:48

2 Answers2

1

Something look strange with your strcontent (he miss the $ on line 39) But to get more simple, use PhpMailer class

It makes your life easy by sending mails

FF MM
  • 138
  • 9
  • Thanks for advice. I've wasted a day trying to configure PHPMailer. Couldn't get it to work. At least this script partially works! – Ben Oct 09 '20 at 07:53
  • you need only to include the library and then is only few line of code, if you want i can help you on that. https://github.com/PHPMailer/PHPMailer#a-simple-example – FF MM Oct 09 '20 at 07:59
  • Thanks for offer! Appreciated. But I had all sorts of problems with PHPMailer. Also, I don't know anything about SMTP so it would probably take you a week to guide me through the setup. – Ben Oct 09 '20 at 08:06
  • Missing $ on line 39 is my typo. The original script is correct. – Ben Oct 09 '20 at 08:12
  • Ok, as you prefer :) In every case you are not forced to use SMTP, you can use the default provider from the host (no config needed) – FF MM Oct 09 '20 at 08:13
  • OK, thanks Fabrizio. I'll look at it again. Many thanks for your input. – Ben Oct 09 '20 at 08:15
  • HI Fabrizio, I wonder if you have any advice on how to solve this error? Many thanks. Ben – Ben Oct 10 '20 at 04:22
  • Checked server logs. Found this error: [Sat Oct 10 03:18:41.480523 2020] [authz_core:error] . – Ben Oct 10 '20 at 04:36
  • looks like an auth error from apache, have a look to this question: https://stackoverflow.com/questions/59638429/ah01630-client-denied-by-server-configuration-htaccess – FF MM Oct 10 '20 at 19:02
  • About your error, your local environment has the mails enabled? Otherwise you can use the smtp option if you have as example a gmail address. The server will be smtp.gmail.com then use your email address and password. Now set as sender your email address. It should work fine. Let me know if bot and i will help you step by step – FF MM Oct 10 '20 at 19:58
0

Make sure you add enctype='multipart/form-data' to your form tag:

<form action='index.php' method='POST' enctype='multipart/form-data'>
  ...
</form>
symlink
  • 11,984
  • 7
  • 29
  • 50