Search code examples
phpsendmailcontact-form

php contact form with attachment doesnt send without file


Sorry guys I am pretty new to PHP, might be obviously easy:
I got a contact form with attachment, but when I try to send it without an attached file, it doesnt send but my error-message appears. I am not sure how to make it possible to send with and without attachment. This is my basic code

if(isset($_POST) && !empty($_POST)) {

// catch spam bots which never loaded contact form
if (!isset($_POST["p3"]) || $_POST["p3"] != "sometext") {  
    header("Location: contactform.php");
    exit;  
}  

// check whether the POST method was used
if ("POST" != getenv("REQUEST_METHOD")) {  
    header("Location: contactform.php");
    exit;  
} 

// check for user-agent and http-referer
if ("" == getenv("HTTP_USER_AGENT") || "" == getenv("HTTP_REFERER")) {
    header("Location: contactform.php");
    exit;  
} 

//  trick the spam bot into identifying itself using a honeypot
if (!empty($_POST["email"])) {
    exit;  
}

//if there is an attachment
if(!empty($_FILES['attachment']['name'])) {
    //store some varables
    $file_name = $_FILES['attachment']['name'];
    $temp_name = $_FILES['attachment']['tmp_name'];
    $file_type = $_FILES['attachment']['type'];

    //get the extension of the file
    $base = basename($file_name);
    $extension = substr($base, strlen($base)-4, strlen($base));

    // only thes file types will be allowed
    $allowed_extensions = array(".doc","docx",".pdf",".zip",".png","jpeg",".jpg",".gif",".txt","docm",".odt","xlsx","xlsm",".csv",".xml",".ods","tiff",".rtf","");

    // check that this file type is allowed
    if(in_array($extension,$allowed_extensions)){

        //mail essentials
        $from = $_POST['mail'];
        $to = "[email protected]";
        $subject = "Anfrage über Website";
        $message = $_POST['quote'];

        // things you need
        $file = $temp_name;
        $content = chunk_split(base64_encode(file_get_contents($file)));
        $uid = md5(uniqid(time()));

        // standard mail headers
        $header = "From: ".$from."\r\n";
        $header .= "Reply-To: ".$to."\r\n";
        $header .= "MIME-Version: 1.0\r\n";

        $header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
        $message .= "This is a multi-part message in MIME format.\r\n";

        // plain text part
        $message .= "--".$uid."\r\n";
        $message .= "Content-Type:text/plain; charset=iso-8859-1\r\n";
        $message .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
        $message .= $message."\r\n\r\n";

        // file attachment
        $message .= "--".$uid."\r\n";
        $message .= "Content-Type: ".$file_type."; name=\"".$file_name."\"\r\n";
        $message .= "Content-Transfer-Encoding: base64\r\n";
        $message .= "Content-Disposition: attachment; filename=\"".$file_name."\"\r\n";
        $message .= $content."\r\n\r\n";

        $msg = "";

        //send the mail 
        if (mail($to, $subject, $message, $header)) {
            $msg = "Ich habe Ihre Mail erhalten und melde mich in Kürze!";
        } else {
            $msg = "Nachricht konnte nicht gesendet werden. Bitte senden Sie mir Ihre Anfrage an [email protected]";
        }
    } else {
        $msg = "Dieser Dateityp kann über das Formular nicht gesendet werden. Bitte senden Sie mir Ihre Anfrage an [email protected]";
    }
} 

// if no file, send anyway (does not work) 
//elseif (empty($_FILES['attachment']['name']) || !(is_uploaded_file($_FILES['attachment']['name']))) {
//}
}

now I tried this code to allow send without attachment, but it doesnt work unfortunately.

  // if no file, send anyway
  elseif (empty($_FILES['attachment']['name']) ||(is_uploaded_file($_FILES['attachment']['name']))) {
  }

Whats wrong or is there any easier way? Please tell me what you need further before downvoting, as it might be not clear. Thank you very much!


Solution

  • I made some changes to your code. (mostly moved around a bit.)

  • I created a variable hasAttachment like the name suggests this contains a boolean if the post contains an attachment.
  • The rest of the changes are extracting the mailing part from your if in which you build the attachment.
  • if (isset($_POST) && !empty($_POST)) {
        // catch spam bots which never loaded contact form
        if (!isset($_POST["p3"]) || $_POST["p3"] != "sometext") {
            header("Location: contactform.php");
            exit;
        }
    
        // check whether the POST method was used
        if ("POST" != getenv("REQUEST_METHOD")) {
            header("Location: contactform.php");
            exit;
        }
    
        // check for user-agent and http-referer
        if ("" == getenv("HTTP_USER_AGENT") || "" == getenv("HTTP_REFERER")) {
            header("Location: contactform.php");
            exit;
        }
    
        //  trick the spam bot into identifying itself using a honeypot
        if (!empty($_POST["email"])) {
            exit;
        }
    
        $hasAttachment = !empty($_FILES['attachment']['name']);
        $uid = md5(uniqid(time()));
    
        // mail essentials
        $from = $_POST['mail'];
        $to = "[email protected]";
        $subject = "Anfrage über Website";
        $message = $_POST['quote'];
    
        // standard mail headers
        $header = "From: " . $from . "\r\n";
        $header.= "Reply-To: " . $to . "\r\n";
        $header.= "MIME-Version: 1.0\r\n";
        $header.= "Content-Type: multipart/mixed; boundary=\"" . $uid . "\"\r\n\r\n";
        $message.= "This is a multi-part message in MIME format.\r\n";
    
        // plain text part
        $message.= "--" . $uid . "\r\n";
        $message.= "Content-Type:text/plain; charset=iso-8859-1\r\n";
        $message.= "Content-Transfer-Encoding: 7bit\r\n\r\n";
        $message.= $message . "\r\n\r\n";
    
        // if there is an attachment
        if ($hasAttachment) {
            // store some varables
            $file_name = $_FILES['attachment']['name'];
            $temp_name = $_FILES['attachment']['tmp_name'];
            $file_type = $_FILES['attachment']['type'];
    
            // get the extension of the file
            $base = basename($file_name);
            $extension = substr($base, strlen($base) - 4, strlen($base));
    
            // only thes file types will be allowed
            $allowed_extensions = array(
                ".doc", "docx", ".pdf", ".zip", ".png", "jpeg", ".jpg", ".gif", ".txt", "docm", ".odt", "xlsx", "xlsm", ".csv", ".xml", ".ods", "tiff", ".rtf", ""
            );
    
            // check that this file type is allowed
            if (in_array($extension, $allowed_extensions)) {
    
                // things you need
                $file = $temp_name;
                $content = chunk_split(base64_encode(file_get_contents($file)));
    
                // file attachment
                $message.= "--" . $uid . "\r\n";
                $message.= "Content-Type: " . $file_type . "; name=\"" . $file_name . "\"\r\n";
                $message.= "Content-Transfer-Encoding: base64\r\n";
                $message.= "Content-Disposition: attachment; filename=\"" . $file_name . "\"\r\n";
                $message.= $content . "\r\n\r\n";
            }
        }
    
        $msg = "";
    
        // send the mail
        if (mail($to, $subject, $message, $header)) {
            $msg = "Ich habe Ihre Mail erhalten und melde mich in Kürze!";
        } else {
            $msg = "Nachricht konnte nicht gesendet werden. Bitte senden Sie mir Ihre Anfrage an [email protected]";
        }
    }