send email with attachment in php using phpmailer


Hey! Are you looking for how to send email in PHP using PHPMailer and add attachments to your messages? In this comprehensive guide, we’ll walk you through the steps to send emails seamlessly within your PHP applications while incorporating attachments for enhanced communication.

Whether you’re building an email contact form, or automating email notifications, this tutorial will provide you with the knowledge and skills you need. Let’s dive in and unlock the potential of PHPMailer for your email needs!

Basically, this post focuses on how to use PHPMailer to send an email with an attachment and we will learn how to send an email via Gmail SMTP Server using PHP contact form. You check this demo also before starting to code.

Sounds great? Let’s move forward to learn how to send email from Gmail using PHPMailer with attachment files from scratch. I am assuming you have a create a project directory in your local or in a server as per your choice.

Check is also: How to Generate PDFs in PHP: A Beginner’s Guide

Discover how to generate PDFs in PHP dynamically! Learn to generate PDFs from HTML, on button click, and save them to a folder with our comprehensive guide.

In this example, I have a project directory as /projects/send-email-in-php-using-phpmailer/

Steps for sending Email in PHP using PHPMailer Contact Form

1. Install PHPMailer Library

So to add PHPMailer we can use composer. A composer is a tool for dependency management in PHP, that allows you to add/install the libraries and packages. You can go to the download page download the Composer-Setup.exe, and get it installed on your machine. To verify the installation open the command prompt and type in composer You will see the version and other information.

Alternatively, if you’re not using Composer, you can download PHPMailer as a zip file and extract it as PHPMailer folder inside your project directory.

To add PHPMailer via composer just open the command prompt inside your project directory and hit the following command or you can refer to the official documentation about this.

composer require phpmailer/phpmailer

2. Get the App Password from Google

In earlier days we used to have Less Secure App an option in Google account settings, we just had to disable it and we were able to send emails using the same Gmail account password.

But things have changed now, Google has upgraded its security policies. So what do I do now? you must be asking this question right? Don’t worry, Let me tell you how because we are using Google’s Gmail so

Open up the link https://myaccount.google.com/apppasswords and sign in with the account you want to send an email from. If you see this screen then first you need to enable 2-Factor Authentication then again open up the link.

Screen if 2-factor Authentication is not enabled.

send email in PHP using PHPMailer_image_1

Screen if 2-factor Authentication is enabled.

send email in PHP using PHPMailer_image_2

So now we have the option to create an App you can name it anything for example YourProjectName Click the create button, a popup will show which has 16 character password copied somewhere remove spaces between if any. This password we can use to send emails from Gmail in PHP using PHPMailer.

3. Create a PHPMailer contact form & email script

In my case, I have used Composer to add the PHPMailer package, so here are the files and folder structure. Don’t worry guys I also covered manual adding of it. The red arrow highlight shows manually added and inside } the curly braces are added by the composer. vendor folder composer.json and composer.lock files are created by the composer itself.

send email in PHP using PHPMailer_image_3

You need to create an attachment folder to store attachment files temporarily, after sending mail we delete them. So let’s create the rest of the files like index.php & email-script.php files, create them, and add the code given code.


<!doctype html>
<html lang="en">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="icon" href="https://codingbirdsonline.com/wp-content/uploads/2019/12/cropped-coding-birds-favicon-2-1-192x192.png" type="image/x-icon">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css">
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.slim.min.js"></script>
    <script type="text/javascript" src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
    <title>Send email in PHP using PHPMailer with attachment | CodingBirdsOnline</title>
    <div class="container">
        <div class="row">
            <div class="col-sm-9 col-md-7 col-lg-5 mx-auto">
                <div class="card card-signin my-5">
                        echo '<div class="alert alert-success">
                                  <strong>Success!</strong> '.$_SESSION['success_message'].'
                        echo '<div class="alert alert-danger">
                                  <strong>Error!</strong> '.$_SESSION['error_message'].'
                    <div class="card-body">
                            <img width="50" src="https://codingbirdsonline.com/wp-content/uploads/2020/01/cropped-coding-birds-online-favicon-192x192.png">
                        <h5 class="card-title text-center">Send email in PHP using PHPMailer with attachment</h5>
                        <form action="email-script.php" method="post" class="form-signin" enctype="multipart/form-data">
                            <div class="form-label-group">
                                <label for="to_email">To <span style="color: #FF0000">*</span></label>
                                <input type="email" name="to_email" id="to_email" class="form-control" placeholder="To" required />
                            </div> <br/>
                            <div class="form-label-group">
                                <label for="subject">Subject <span style="color: #FF0000">*</span></label>
                                <input type="text" name="subject" id="subject" class="form-control" placeholder="Subject" required/>
                            </div> <br/>
                            <label for="contact">Attachment</label>
                            <div class="form-label-group">
                                <input type="file" id="attachment" name="attachment"/>
                            <label for="subject">Message <span style="color: #FF0000">*</span></label>
                            <div class="form-label-group">
                                <textarea type="text" id="message" name="message"  class="form-control" placeholder="Message" required></textarea>
                            </div><br/> <br/>
                            <button type="submit" name="sendMailBtn" value="Send Email" class="btn btn-lg btn-primary btn-block text-uppercase" >Send Email</button>

The form tag has an action to the email-script.php file, so here is the code for it.


require 'vendor/autoload.php'; // <-- keep this line if using composer
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;

//require 'PHPMailer/src/PHPMailer.php'; //<-- Add these files manually if not using composer
//require 'PHPMailer/src/Exception.php'; //<-- Add these files manually if not using composer
//require 'PHPMailer/src/SMTP.php'; //<-- Add these files manually if not using composer

    $to = $_POST['to_email'];
    $subject = $_POST['subject'];
    $message = $_POST['message'];
    $attachment = $_FILES['attachment']['tmp_name'];
    $emailAttachment = null;
        $attachmentDir = 'attachment/';
        $emailAttachment = $attachmentDir. $_FILES['attachment']['name'];
         * Add file type validation
        $fileExtension = pathinfo($emailAttachment,PATHINFO_EXTENSION);
        if(!in_array($fileExtension, array('pdf', 'doc', 'docx', 'jpg', 'png', 'jpeg'))){
            $_SESSION['error_message'] = "Invalid file type: Only pdf, doc, docx, jpg, png, jpeg are allowed";
            header('Location: ' . $_SERVER['HTTP_REFERER']);
        move_uploaded_file($attachment, $emailAttachment);
    sendEmail($to, $subject, $message, $emailAttachment);
     * Delete the uploaded attachment file after email sent

 * Sends email with attachment
 * @param $to
 * @param $subject
 * @param $message
 * @param $emailAttachment
function sendEmail($to, $subject, $message, $emailAttachment) {
    try {
        $mail = new PHPMailer(true);
        $mail->SMTPDebug = SMTP::DEBUG_OFF;
        $mail->Host = 'smtp.gmail.com';
        $mail->SMTPAuth = true;
        $mail->Username = 'yourEmail@gmail.com';
        $mail->Password = 'xxxxxxxxxxxYourPassword'; // <-- which we generated from step2
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
        $mail->Port = 465;

        $mail->setFrom('yourEmail@gmail.com', 'Coding Birds'); //<-- 2nd param is optional
        $mail->addAddress($to, 'Ankit'); //<-- 2nd param is optional

        $mail->isHTML(false); //<-- make it true if sending HTML content as message
        $mail->Subject = $subject;
        $mail->Body = $message;
        $_SESSION['success_message'] = "Email Message has been sent successfully";
    }catch (Exception $e){
        $_SESSION['error_message'] =  "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
    header('Location: ' . $_SERVER['HTTP_REFERER']);

3. Run the code

Boom!!!! our job is done, So let’s try to execute and run the code, if you are following the same folder structure then open http://localhost/projects/send-email-in-php-using-phpmailer You should see this screen if everything went well.

send email in PHP using PHPMailer_image_4

Now let’s fill in the information in the form and click the SEND EMAIL button. If all goes well you will see the success message right at the top:

send email in PHP using PHPMailer_image_5
Gmail inbox email received_image_6

So I got the mail with an attachment you can see, And if something goes wrong, you see the error message as well instead of the success message at the same place. To simulate the error scenario I used the wrong password then this error came out.

Email sending failed received_image_7

Source Code & Demo

You can download the full 100% working source code from here. If You have gone through all the above steps then you can check this demo also before starting to code.


I hope you learned something from this post. If you have any suggestions they would be appreciated. And if you have any errors or issues please comment definitely I will try to help.

If this code works for you, please leave a nice ❤️ comment so that others can find it useful which always gives me the motivation to create such content.

Hi, If you are looking for the PHP script to learn how to send email with attachment in PHP without going to spam then you are in the right place. I know you searched a lot on Google to find source code but every code sends that to spam, not in the inbox. Check our demo to confirm.

Here I am going to give a PHP script by which your email with an attachment will always go to inbox. Sending an email with attachment is the most common task in web development.

When you are applying for a job or submitting any application, you often might be noticed that they accept a file to upload. It may be anything like your CV or resume, profile picture or any other document.

Sending details to email is sometimes good in terms of saving space on our server. Since we are not storing the details on our database or attachment to our server folders.

How to do that?

Here we will use a simple HTML form accepting basic details like name, email, subject, message, and an attachment. The attachment has a validation that only PDF, DOC, JPG, JPEG, & PNG files are allowed to upload. In the previous tutorial, we learned about how to send email in PHP step by step but here we will do the same with attachment.

So what are we waiting for? Let’s start. Check the files and folder we are going to create.

  • index.php is the main file which is a simple HTML form as I told above.
  • email-script.php is the script file that sends an email with an attachment.
  • validation-script.js is a javaScript validation file.
  • uploads folder saves the attachment to send emails and deletes later.

Now we should create these files. I am giving you just code block here. Make sure you put these CDN in to head off your index.php to work your code.

   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

And include this javaScript validation file also before closing to the body tag.

<script src="validation-script.js"></script>


    <div class="container">
        <div class="row">
            <div class="col-lg-8 posts-list">
                <div class="card card-signin my-5">
                    <div class="card-body">
                        <center><img src="../website/img/coding-birds-online/coding-birds-online-favicon.png" width="70"></center>
                        <h5 class="card-title text-center">Send email with attachment in PHP</h5>
                        <form method="post" action="email-script.php" enctype="multipart/form-data" id="emailForm">
                            <div class="form-group">
                                <input type="text" name="name" id="name" class="form-control" placeholder="Name" >
                                <div id="nameError" style="color: red;font-size: 14px;display: none">nameError</div>
                            <div class="form-group">
                                <input type="email" name="email" id="email" class="form-control" placeholder="Email address" >
                                <div id="emailError" style="color: red;font-size: 14px;display: none">emailError</div>
                            <div class="form-group">
                                <input type="text" name="subject" id="subject" class="form-control"  placeholder="Subject" >
                                <div id="subjectError" style="color: red;font-size: 14px;display: none">subjectError</div>
                            <div class="form-group">
                                <textarea name="message" id="message" class="form-control" placeholder="Write your message here"></textarea>
                                <div id="messageError" style="color: red;font-size: 14px;display: none">messageError</div>
                            <div class="form-group">
                                <input type="file" name="attachment" id="attachment" class="form-control">
                                <div id="attachmentError" style="color: red;font-size: 14px;display: none">attachmentError</div>
                            <div class="submit">
                                <input type="submit" name="submit" onclick="return validateEmailSendForm();" class="btn btn-success" value="SUBMIT">

If you notice this form uses an action to email-script.php this file. Create this file also.



    // Get the submitted form data
    $email = $_POST['email'];
    $name = $_POST['name'];
    $subject = $_POST['subject'];
    $message = $_POST['message'];
    $uploadStatus = 1;

    // Upload attachment file

        // File path config
        $targetDir = "uploads/";
        $fileName = basename($_FILES["attachment"]["name"]);
        $targetFilePath = $targetDir . $fileName;
        $fileType = pathinfo($targetFilePath,PATHINFO_EXTENSION);

        // Allow certain file formats
        $allowTypes = array('pdf', 'doc', 'docx', 'jpg', 'png', 'jpeg');
        if(in_array($fileType, $allowTypes)){
            // Upload file to the server
            if(move_uploaded_file($_FILES["attachment"]["tmp_name"], $targetFilePath)){
                $uploadedFile = $targetFilePath;
                $uploadStatus = 0;
                $statusMsg = "Sorry, there was an error uploading your file.";
            $uploadStatus = 0;
            $statusMsg = 'Sorry, only PDF, DOC, JPG, JPEG, & PNG files are allowed to upload.';

    if($uploadStatus == 1){
        // Recipient
        $toEmail = $email;
        // Sender
        $from = 'info@codingbirdsonline.com';
        $fromName = 'Coding Birds Online';
        // Subject
        $emailSubject = 'Email attachment request Submitted by '.$name;
        // Message
        $htmlContent = '<h2>Contact Request Submitted</h2>
                <p><b>Name:</b> '.$name.'</p>
                <p><b>Email:</b> '.$email.'</p>
                <p><b>Subject:</b> '.$subject.'</p>

        // Header for sender info
        $headers = "From: $fromName"." <".$from.">";

        if(!empty($uploadedFile) && file_exists($uploadedFile)){
            // Boundary
            $semi_rand = md5(time());
            $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
            // Headers for attachment
            $headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\"";
            // Multipart boundary
            $message = "--{$mime_boundary}\n" . "Content-Type: text/html; charset=\"UTF-8\"\n" .
                "Content-Transfer-Encoding: 7bit\n\n" . $htmlContent . "\n\n";
            // Preparing attachment
                $message .= "--{$mime_boundary}\n";
                $fp =    @fopen($uploadedFile,"rb");
                $data =  @fread($fp,filesize($uploadedFile));
                $data = chunk_split(base64_encode($data));
                $message .= "Content-Type: application/octet-stream; name=\"".basename($uploadedFile)."\"\n" .
                    "Content-Description: ".basename($uploadedFile)."\n" .
                    "Content-Disposition: attachment;\n" . " filename=\"".basename($uploadedFile)."\"; size=".filesize($uploadedFile).";\n" .
                    "Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";

            $message .= "--{$mime_boundary}--";
            $returnpath = "-f" . $email;
            // Send email
            $mail = mail($toEmail, $emailSubject, $message, $headers, $returnpath);
            // Delete attachment file from the server
            // Set content-type header for sending HTML email
            $headers .= "\r\n". "MIME-Version: 1.0";
            $headers .= "\r\n". "Content-type:text/html;charset=UTF-8";
            // Send email
            $mail = mail($toEmail, $emailSubject, $htmlContent, $headers);

        // If mail sent
            $statusMsg = 'Your email attachment request has been submitted successfully !';
            $statusMsg = 'Your request submission failed, please try again.';
    echo '<script>alert("'.$statusMsg.'");window.location.href="./";</script>';


function validateEmailSendForm() {
   var name = $("#name").val();
   var email = $("#email").val();
   var subject = $("#subject").val();
   var message = $("#message").val();
   var attachment = $("#attachment").val();

   if (name == ""){
       $("#nameError").html("Please enter your name");
       return false;
   }else  if (email == ""){
       $("#emailError").html("Please enter your email");
       return false;
   }else  if (!validateEmail(email)){
       $("#emailError").html("Please enter valid email");
       return false;
   }else  if (subject == ""){
       $("#subjectError").html("Please enter subject");
       return false;
   }else if (message == ""){
       $("#messageError").html("Please enter some message");
       return false;
   }else if (attachment == ""){
       $("#attachmentError").html("Please select a attachment");
       return false;
       return true;

    function validateEmail(inputText) {
        var mailformat = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
        if(inputText.match(mailformat)) {
            return true;
        } else{
            return false;

Run the code!

Now it is time to run and test our code. If you did everything step by step then you will not face any errors and you will get output something like this.


This form is validated properly like empty fields, valid email and attachment file accepted. When you fill that form and hit the submit button then you will get the alert message of success or errors.

Check this also How to make a dynamic pie chart in PHP in 2 steps.

Attention !!! It may take 1 or 2 minutes to receive email with attachment so please have patience. But I am sure you will receive in primary inbox not to spam.


Source Code & Demo

You can download the full 100% working source code from here. You check this demo also.


I hope you learned explained above, If you have any suggestions, are appreciated. And if you have any errors comment here. You can download the full 100% working source code from here.

Ok, Thanks for reading this article, see you in the next post.

Happy Coding 🙂