skip to Main Content

I am trying to send an email from our website, hosted on BlueHost, that includes an attachment. We found out that as of August 2015, our original script would no longer send emails to our email.

Fast forward to now, we are trying to fix this email issue, but are having no luck. Originally, our code was using the old mail() approach. Below is the attempted fix to this approach (which returns no PHP/log errors):

<?php
if(!isset($_POST["email"]) && !isset($_POST["name"]))
{
    echo "Error: Form Not Submitted.n Name and email are mandatory!Please Click the back button to return to the website.n";
    //Set Variables
    $company = $_POST["company"];
    $address = $_POST["address"];
    $phone = $_POST["phone"];
    $name = $_POST["name"];
    $position = $_POST["position"];
    $visitor_email = $_POST["email"];
    $message = $_POST["message"];
    $submitVar = $_POST["submit"];
    echo "$company, $address, $phone, $name, $position, $visitor_email, $message rn";
}
else{
    //Set Variables
    $company = $_POST["company"];
    $address = $_POST["address"];
    $phone = $_POST["phone"];
    $name = $_POST["name"];
    $position = $_POST["position"];
    $visitor_email = $_POST["email"];
    $message = $_POST["message"];
    echo "$company, $address, $phone, $name, $position, $visitor_email, $message rn";

    if(IsInjected($visitor_email))
    {
        echo "Bad email value!";
        exit;
    }

    //***Lay out Message***//   
    $to = "[email protected]";
    $email_from = $visitor_email;
    $email_subject = "Website Form Submission from $company";
    $email_body = "Dear Email Target,nn $messagennSincerely,nn$namen$positionnn$companyn$addressn$phone";

    //***Attatch the file***//
    $filename = $_FILES['attachment1']['tmp_name'];
    $filetype = $_FILES['attachment1']['tmp_type'];
    $filesize = $_FILES['attachment1']['tmp_size'];  // get size of the file for size validation
    if($filesize > 0){
        $handle = fopen($filename, "r");
        $content = fread($handle, $filesize);
        fclose($handle);
        $attachment = chunk_split(base64_encode($content));
    }

    //*** Establish Boundary ***//  
    $boundary = md5(date('r', time()));

    //***Start Header***//
    $headers = "MIME-Version: 1.0rn";
    $headers = "X-Mailer: PHP/" . phpversion()."rn";
    $headers .= "From: ".$name." <".$email_from.">rn";
    $headers .= "To: ".$email."rn";
    $headers .= "Subject: $email_subjectrn";
    $headers .= "Reply-To: ".$visitor_email."rn";
    $headers .= "Content-Type: multipart/mixed"; 
    $headers .= "boundary = "".$boundary.""rnrn";

    //***Message Section***//
    $body = "--$boundaryrn"; 
        $body .= "Content-Type: text/plain; charset=ISO-8859-1rn"; 
        $body .= "Content-Transfer-Encoding: base7rnrn";  
        $body .= $email_body;

    //***Attachment Section***//;
    if($filesize > 0){
        $body .= "--$boundaryrn"; 
        $body .="Content-Type:".$filetype."; name="".$filename.""rn"; 
        $body .="Content-Disposition: attachment; filename=".$filename."rn"; 
        $body .="Content-Transfer-Encoding: base64rn"; 
        $body .="X-Attachment-Id: ".rand(1000, 99999)."rnrn";  
        $body .= $attachment."rnrn"; // Attaching the encoded file with email 
    }

    //***End Email***///
    $body .= "--$boundary--";

    //Send the email!
    $test = mail($to, $email_subject, $body, $headers);
    if($test){
        echo "TRUE";
        //done. redirect to thank-you page.
        header("Location: ./Sales_Quotes.html"); 
        echo '<h5 class="contentHeader simple">Form Submitted!</h5>';
        /* Redirect browser */
        exit();/*Good Practice*/
    } else {
        die("Error: PHP mail() failure!rn"
        .$to."rn"
        .$email_subject."rn"
        .$body."rn"
        .$headers."rn");
    }
}

// Function to validate against any email injection attempts
function IsInjected($str)
{
    $injections = array('(n+)',
      '(r+)',
      '(t+)',
      '(%0A+)',
      '(%0D+)',
      '(%08+)',
      '(%09+)'
      );
    $inject = join('|', $injections);
    $inject = "/$inject/i";
    if(preg_match($inject,$str))
    {
        return true;
    }
    else
    {
        return false;
    }
}
?> 

Both a localhost running Debian 10.2 and BlueHost tell me that the mail() function fails when I call it. Where did I go wrong? As I was getting nowhere on this after 2 days of work, since everyone seems to want me to use PHPMailer, I also created a second script with the PHPMailer approach and it also fails the exact same way (no log/php errors, telling me that the call failed):

<?php
require_once './PHPMailer.php';
require_once './Exception.php';
use PHPMailerPHPMailerPHPMailer;
if(!isset($_POST["email"]) && !isset($_POST["name"]))
{
    echo "Error: Form Not Submitted.n Name and email are mandatory!Please Click the back button to return to the website.n";
    //Set Variables
    $company = $_POST["company"];
    $address = $_POST["address"];
    $phone = $_POST["phone"];
    $name = $_POST["name"];
    $position = $_POST["position"];
    $visitor_email = $_POST["email"];
    $message = $_POST["message"];
    $submitVar = $_POST["submit"];
    echo "$company, $address, $phone, $name, $position, $visitor_email, $message rn";
}
else{
    //***Set Variables***//
    $company = $_POST["company"];
    $address = $_POST["address"];
    $phone = $_POST["phone"];
    $name = $_POST["name"];
    $position = $_POST["position"];
    $visitor_email = $_POST["email"];
    $message = $_POST["message"];
    echo "$company, $address, $phone, $name, $position, $visitor_email, $message rn";

    if(IsInjected($visitor_email))
    {
        echo "Bad email value!";
        exit;
    }

    //***Lay out Message***//   
    $to = "[email protected]";
    $email_from = $visitor_email;
    $email_subject = "Website Form Submission from $company";
    $email_body = "Dear Target,nn $messagennSincerely,nn$namen$positionnn$companyn$addressn$phone";

    //***Upload the file***//
    $filename = $_FILES['attachment1']['tmp_name'];
    $filetype = $_FILES['attachment1']['type'];
    $filesize = $_FILES['attachment1']['size'];  // get size of the file for size validation
    if($filesize > 0){
        $attachment = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['attachment1']['name']));
        if (!(move_uploaded_file($_FILES['attachment1']['tmp_name'], $uploadfile))){
            echo "Failed to Upload File Properly.";
        }
    }

    //***Create the PHPMailer Message***//:
    $mail = new PHPMailer(true);
    $mail -> setFrom($email_from,$name);
    $mail -> To = "[email protected]";
    $mail -> addAddress("[email protected]", "Mr. Example");
    $mail -> Subject = $email_subject;
    $mail -> Body = $email_body;
    if($filesize > 0){
        //***Attach the file***//
        $mail ->addAttachment($uploadfile,$filename);
    }

    //***Send the email!***//
    if(!$mail->send()){
        echo "TRUE";
        //done. redirect to thank-you page.
        header("Location: ./Sales_Quotes.html"); 
        echo '<h5 class="contentHeader simple">Form Submitted!</h5>';
        /* Redirect browser */
        exit();/*Good Practice*/
    } else {
        die("Error: PHP mail() failure!rn"
        .$to."rn"
        .$email_subject."rn"
        .$email_body."rn");
    }
}

// Function to validate against any email injection attempts
function IsInjected($str)
{
    $injections = array('(n+)',
      '(r+)',
      '(t+)',
      '(%0A+)',
      '(%0D+)',
      '(%08+)',
      '(%09+)'
      );
    $inject = join('|', $injections);
    $inject = "/$inject/i";
    if(preg_match($inject,$str))
    {
        return true;
    }
    else
    {
        return false;
    }
}
?> 

Is there any simple solution/correction to the above that fulfills the following requirements?:

  • No SMTP. Localhost preferred.
  • Quick/Easy Setup
  • Must support an
    optional attachment from user
  • Must be viable for BlueHost.

Note that this is for a small business in the manufacturing industry.
I’m at my wits end and I’ve already spent too much time on this. Any help would be greatly appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    After quite a lot of testing and debugging, the final code came out to be the following:

    <?php
    require_once './PHPMailer.php';
    require_once './Exception.php';
    use PHPMailerPHPMailerPHPMailer;
    if(!isset($_POST["email"]) && !isset($_POST["name"]))
    {
        echo "Error: Form Not Submitted.n Name and email are mandatory! Please Click the back button to return to the website.n";
        //Set Variables
        $company = $_POST["company"];
        $address = $_POST["address"];
        $phone = $_POST["phone"];
        $name = $_POST["name"];
        $position = $_POST["position"];
        $visitor_email = $_POST["email"];
        $message = $_POST["message"];
        $submitVar = $_POST["submit"];
        echo "$company, $address, $phone, $name, $position, $visitor_email, $message rn";
    }
    else{
        //***Set Variables***//
        $company = $_POST["company"];
        $address = $_POST["address"];
        $phone = $_POST["phone"];
        $name = $_POST["name"];
        $position = $_POST["position"];
        $visitor_email = $_POST["email"];
        $message = $_POST["message"];
        //echo "$company, $address, $phone, $name, $position, $visitor_email, $message rn";
    
        if(IsInjected($visitor_email))
        {
            echo "Bad email value!";
            exit;
        }
    
        //***Lay out Message***//   
        $to = "[email protected]";
        $email_from = $visitor_email;
        $email_subject = "Website Form Submission from $company";
        $email_body = "Dear Target Company,nn $messagennSincerely,nn$namen$positionnn$companyn$addressn$phone";
    
        //***Upload the file***//
        $filename = $_FILES['attachment1']['tmp_name'];
        $filetype = $_FILES['attachment1']['type'];
        $filesize = $_FILES['attachment1']['size'];  // get size of the file for size validation
        if($filesize > 0){
            $attachment = tempnam(sys_get_temp_dir(), hash('sha256', $_FILES['attachment1']['name']));
            if (!(move_uploaded_file($_FILES['attachment1']['tmp_name'], $uploadfile))){
                echo "Failed to Upload File Properly.";
            }
        }
    
        //***Create the PHPMailer Message***//:
        $mail = new PHPMailer(true);
        $mail -> setFrom($email_from,$name);
        $mail -> To = "[email protected]";
        $mail -> addAddress("[email protected]", "Mr Example");
        $mail -> Subject = $email_subject;
        $mail -> Body = $email_body;
        if($filesize > 0){
            //***Attach the file***//
            $mail ->addAttachment($uploadfile,$filename);
        }
    
        //***Send the email!***//
        try{
            $mail->send();
            //done. redirect to thank-you page.
            header("Location: ./Sales_Quotes.html"); 
            echo '<h5 class="contentHeader simple">Form Submitted!</h5>';
            /* Redirect browser */
            exit();/*Good Practice*/
        }
        catch (phpmailerException $e) {
            echo "Error: PHPMailer failure!: ";
            echo $e->errorMessage();  //PHPMailer error messages
            echo $mail->ErrorInfo;
        }
        catch (Exception $e) {
            echo "Error: PHPMailer failure!: ";
            echo $e->getMessage();  // other error messages
            echo $mail->ErrorInfo;
        }
    }
    
    // Function to validate against any email injection attempts
    function IsInjected($str)
    {
        $injections = array('(n+)',
          '(r+)',
          '(t+)',
          '(%0A+)',
          '(%0D+)',
          '(%08+)',
          '(%09+)'
          );
        $inject = join('|', $injections);
        $inject = "/$inject/i";
        if(preg_match($inject,$str))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    ?> 
    

    Turns out many of the examples and answers out there for PHPMailer are mis-typed or bad references. For anyone looking to NOT use SMTP and include an attachment, this code should work (minimally send the email) on BlueHost.


  2. Tye to put this at start and at end of mail output:
    Ob_start();
    Ob_end_clean();

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search