[SOLVED] Sending mail attachment in NextJS+Axios+PHPMailer

Issue

This Content is from Stack Overflow. Question asked by u238

I’m struggling to send an email with attachment. The problem is only attachment, sending mail is OK.

My Form :

 <form onSubmit={handleSubmita}>
            <input
              type="text"
              placeholder="Name"
              id="app-user"
              name="app-user"
              required
              onChange={(e) => setForma({ ...forma, name: e.target.value })}
            />
            <input
              type="mail"
              placeholder="EMail (example@example.com)"
              id="app-mail"
              name="app-mail"
              pattern="^.+@.+.[a-zA-Z]{2,63}$"
              required
              onChange={(e) => setForma({ ...forma, mail: e.target.value })}
            />
            <input
              type="text"
              placeholder="Mobile"
              id="app-mobile"
              name="app-mobile"
              required
              onChange={(e) => setForma({ ...forma, mobile: e.target.value })}
            />
            <input
              type="text"
              placeholder="department"
              id="app-department"
              name="app-department"
              required
              onChange={(e) => setForma({ ...forma, department: e.target.value })}
            />
            <input
              type="text"
              placeholder="Title"
              id="app-title"
              name="app-title"
              required
              onChange={(e) => setForma({ ...forma, title: e.target.value })}
            />
            <label
              htmlFor="app-file"
              className="w-full subpixel-antialiased text-sm flex items-center mt-1"
            ><AiOutlineFileText />Upload file
            </label>
            <input
              type="file"
              id="app-file"
              name="app-file"
              accept=".doc, .docx ,.pdf"                  
              required
              className='mt-1'
              onChange={(e) => setForma({ ...forma, file: e.target.files[0] })}
            />
            <div className="flex justify-evenly w-full bg-slate-200 my-3 xxs:flex-col p-2">
              <button
                className="flex justify-center items-center bg-red-100 mx-1 xxs:m-0"
                onClick={() => {
                  setForm(0)
                  setFull(false)
                }}
              >
                <AiOutlineDoubleLeft size={20} />{' '}
                <span className="ml-2">Back</span>
              </button>
              <button
                className="flex justify-center items-center bg-emerald-100 mx-1 xxs:m-0 xxs:mt-2"
                id="app-btn-submit"
                type="submit"
              >
                <AiOutlineSend size={20} />{' '}
                <span className="ml-2">Send!</span>
              </button>
            </div>
          </form>

As you can see I store form’s data in a useState, it’s like

const [forma, setForma] = useState({
name: '',
mail: '',
mobile:'',
department:"",
title:"",
file:""

})

When a user clicks the submit button, axios runs,

const handleSubmita = (e) => {
e.preventDefault()
console.log(forma)
setSpinner(true)

axios({
  method: 'post',
  url: process.env.NEXT_PUBLIC_URL_A, //URL comes from .env file
  headers: { 'content-type': 'application/json' },
  data: forma,
})
  .then((result) => {
    console.log(result.data)
    if (result.data == '200') {
      setSpinner(false)
      setResultqform(true)
    } else {
      setSpinner(false)
      setError(true)
    }
  })
  .catch((error) => console.log('error'))

}

PHP Side

<?php

  header('Access-Control-Allow-Origin: *');
  header('Access-Control-Allow-Headers: Content-Type');
  $rest_json = file_get_contents('php://input');
  $_POST = json_decode($rest_json, true);
  
  use PHPMailerPHPMailerPHPMailer;

  if (
      isset($_POST['name']) &&
      isset($_POST['mail']) &&
      isset($_POST['file']) &&
      isset($_POST['title']) &&
      isset($_POST['mobile']) &&
      isset($_POST['department'])
  ) {
var_dump($_POST);
$_POST['name'] = htmlentities($_POST['name']);
$_POST['mail'] = htmlentities($_POST['mail']);
$_POST['title'] = htmlentities($_POST['title']);
$_POST['mobile'] = htmlentities($_POST['mobile']);
move_uploaded_file( $_FILES[$_POST['file']]['tmp_name'],"tmp/".$_FILES[$_POST['file']]['name']);
require_once 'PHPMailer/PHPMailer.php';
require_once 'PHPMailer/SMTP.php';
require_once 'PHPMailer/Exception.php';

$mail = new PHPMailer();
date_default_timezone_set('Europe/London');
$now = date_create()->format('Y-m-d H:i:s');
try {
    $mail->isSMTP(); //Send using SMTP
    $mail->Host = $Host; //Set the SMTP server to send through
    $mail->SMTPAuth = true; //Enable SMTP authentication
    $mail->Username = $uname; //SMTP username
    $mail->Password = $pass; //SMTP password
    $mail->SMTPSecure = 'ssl'; //Enable implicit TLS encryption
    $mail->Port = $port;
    $mail->CharSet = 'UTF-8';

    $mail->setFrom($mailer, 'Mailer');
    $mail->addAddress($recipent, $recipent_info); //Add a recipient
    $mail->addReplyTo($_POST['mail'], $_POST['name']);

    $file_tmp = $_FILES[$_POST[$_POST['file']]]['tmp_name'];
    $file_name = $_FILES[$_POST[$_POST['file']]]['name'];
    $mail->AddAttachment($file_tmp, $file_name);

    //Content
    $mail->isHTML(true); //Set email format to HTML
    $mail->Subject = 'Test';
    $mail->Body =
        '<b>' .
        $_POST['name'] .
        '</b> =name<br/><br/>';
    $mail->Body .=
        '<b>department:</b> ' .
        $_POST['department'] .
        '<br/><br/>';
    $mail->Body .=
        '<b>title:</b> ' . $_POST['title'] . '<br/><br/>';
    $mail->Body .= '<b>Mobile:</b> ' . $_POST['mobile'] . '<br/><br/>';
    $mail->Body .= '<b>Mail:</b> ' . $_POST['mail'] . '<br/><br/>';
    $mail->Body .= '<b>Time: </b>' . $now;

    //$mail->send();

    if ($mail->send()) {
        echo '200';
        echo $_POST;
    } else {
        echo $mail->ErrorInfo;
    }
} catch (Exception $e) {
    echo "Error! Mailer Error: {$mail->ErrorInfo}";
}
  }

  ?>

Axios send file’s data but PHP doesn’t get it, I don’t understand why. Here is screenshot, (mail is being sent without attachment).

enter image description here

It’s the first time, I am trying to send an attachment. if I’m doing it the wrong way, pls advise.



Solution

Finally I solved the problem. I am writing the solution maybe someone has similar problems.

1- In axios, I changed the code "headers: { ‘content-type’: ‘application/json’ }," with "headers: { ‘Content-Type’: ‘multipart/form-data’ },". That makes sense since I also want to send file infos.

2- In PHP, I learnt that files can be sent through POST method but they need to handle by using FILES method. So my code became

///////////Strings
$name = htmlspecialchars($_POST['name']);
$mail_sender = htmlspecialchars($_POST['mail']);
$title = htmlspecialchars($_POST['title']);
$department = htmlspecialchars($_POST['department']);
$mobile = htmlspecialchars($_POST['mobile']);
$status = htmlspecialchars($_POST['status']);

///////////Attachment Info
$file_name=$_FILES['file']['name'];
$file_tmp=$_FILES['file']['tmp_name'];

In PHP, I add these data to send attacchment.

$mail->AddAttachment($file_tmp, $file_name);

Also, I removed the move_uploaded_file line since I don’t need to store files, just want to send it through an email.

And that’s it, it works perfectly now.


This Question was asked in StackOverflow by u238 and Answered by u238 It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?