👾 php

phpmailer ajax 사용 폼메일 + 구글캡챠 v3

(。θᗨθ。) 2024. 1. 9. 09:26

1. phpmailer 설치

https://github.com/PHPMailer/PHPMailer

 

GitHub - PHPMailer/PHPMailer: The classic email sending library for PHP

The classic email sending library for PHP. Contribute to PHPMailer/PHPMailer development by creating an account on GitHub.

github.com

 

2. form 만들기

<!doctype html>
<html lang="ko">

<head>
  <meta charset="utf-8">
  <title>PHP</title>
  <style>
    body {
      font-family: sans-serif;
    }

    input,
    textarea {
      font-family: sans-serif;
    }

    textarea {
      width: 600px;
      height: 300px;
    }
  </style>
</head>

<body>

  <!-- ajax 안쓸때 ssss -->
  <!-- <form method="post" class="contact-frm" id="frm" name="frm" enctype="multipart/form-data" action="send_form.php"> -->
  <!-- ajax 안쓸때 eeee -->
  <form method="post" class="contact-frm" id="frm" name="frm" enctype="multipart/form-data" onsubmit="return false;"> <!-- onsubmit="return false; << 문의하기 취소시 새로고침 안되게 -->

    <p class="info">* 표시 된 항목은 필수 입력 항목입니다.</p>
    <hr>
    <div class="line noline">
      <div class="cont">
        <p class="area-name">* 문의유형 TYPE</p>
        <select id="H_ContactType" name="H_ContactType">
          <option value="견적문의 및 상담">견적문의 및 상담</option>
          <option value="A/S">A/S</option>
          <option value="인사팀">인사팀</option>
        </select>
      </div>
    </div>
    <div class="line dF">
      <div class="cont">
        <p class="area-name">* 고객명 NAME</p><!-- .area-name -->
        <input type="text" id="H_Name" name="H_Name" placeholder="ex) 홍길동" required>
      </div><!-- .cont -->
      <div class="cont">
        <p class="area-name">회사명 COMPANY</p><!-- .area-name -->
        <input type="text" id="H_Corp" name="H_Corp" placeholder="ex) 회사이름">
      </div><!-- .cont -->
      <div class="cont">
        <p class="area-name">* 연락처 CONTACT</p><!-- .area-name -->
        <input type="number" id="H_Tel" name="H_Tel" placeholder="' - ' 없이 입력해주세요." required>
      </div><!-- .cont -->
      <div class="cont">
        <p class="area-name">* 이메일 E-MAIL</p><!-- .area-name -->
        <input type="email" id="H_Email" name="H_Email" placeholder="ex) mail@mail.com" required>
      </div><!-- .cont -->
    </div><!-- .line -->
    <div class="noline line">
      <div class="cont">
        <p class="area-name">* 제목 TITLE</p><!-- .area-name -->
        <input type="text" id="H_Title" name="H_Title" placeholder="ex) oo제품 문의 남깁니다." required>
      </div><!-- .cont -->
    </div><!-- .line -->
    <div class="line">
      <div class="cont noCenter">
        <p class="area-name">* 문의내용 MESSAGE</p><!-- .area-name -->
        <textarea id="H_Content" name="H_Content" placeholder="문의내용을 입력해주세요. &#10;자세히 적어주시면 더욱 상세한 답변을 전해드릴 수 있습니다." required></textarea>
      </div><!-- .cont -->
    </div><!-- .line -->
    <div class="line file">
      <div class="cont">
        <p class="area-name">첨부파일 ATTACHMENT</p><!-- .area-name -->
        <input type="file" id="H_File" name="H_File">
      </div><!-- .cont -->
    </div><!-- .line -->
    <div class="footer">
      <div class="agree">
        <input type="checkbox" name="agree" id="agree" onClick="agreeCheck(this.form)">
        <label bel for="agree">개인정보 수집 및 이용에 대한 내용을 읽었으며, 위 내용에 동의합니다. </label>
      </div>
      <input type="hidden" id="g-recaptcha" name="g-recaptcha">
      <button type="submit" form="frm" value="보내기" class="btn-submit" onclick="$confirm();" name="button" disabled>
        <span>문의하기</span>
      </button>
      <div id="result"></div>
    </div><!-- .line -->
  </form>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
  <script src='https://www.google.com/recaptcha/api.js?render=@@@'></script>

  <script type="text/javascript">
    grecaptcha.ready(function() {
      grecaptcha.execute('@@@', {
        action: 'submit'
      }).then(function(token) {
        document.getElementById('g-recaptcha').value = token;
      });
    });
  </script>
<script>
      const $button = $(".btn-submit");

      function agreeCheck(frm) {

        if ($button.is(":disabled"))
          $button.removeAttr("disabled");
        else
          $button.attr("disabled", true);


      }

      function validateEmail(email) {
        var regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
        return regex.test(email);
      }

      function validateForm() {
        var isValid = true;

        // 필수 입력란을 확인합니다.
        $('.contact-frm input[required], .contact-frm textarea[required]').each(function() {
          if ($.trim($(this).val()) == '') {
            isValid = false;
            // 빈 값이 있을 경우 해당 입력란의 placeholder를 사용하여 경고를 표시합니다.
            var placeholder = $(this).prev('.item__tit').text();
            let replaced_str = placeholder.replace('*', '');
            alert("'" + replaced_str + "'" + "을(를) 입력해주세요.");
            return false; // 검증 중단
          }
        });


        var email = $('#H_Email').val();
        if (!validateEmail(email)) {
          isValid = false;
          alert("올바른 이메일 주소를 입력해주세요.");
        }
        return isValid;
      }


      function $confirm() {


        if (confirm('문의하시겠습니까?')) {
          // ajax 안쓸때-ssss
          // $("form").attr("action", "send_form.php");
          // $("form").submit();
          // alert('전송되었습니다.')
          // ajax 안쓸때-eeee

          if (validateForm()) {
            // 전송 가능하면 Ajax 전송을 시작합니다.
            // 이하 코드는 기존과 동일


            //Ajax 전송 시작 ssssssssssss
            $('#result').html("<font color='blue'>전송중입니다. 잠시 기다려주세요.</font>");
            var form = $("form")[0];
            var formData = new FormData(form);
            $.ajax({
              url: "send_form.php",
              processData: false,
              contentType: false,
              data: formData,
              type: "POST",
              cache: false,
              success: function(args) {

                $('#result').html(args);
                $('#frm').trigger("reset");


                $('#result').html("");
                $button.attr("disabled", true);
                alert('전송되었습니다.');
                document.getElementById('H_File').value = null;
                document.querySelector(".likeInput").innerText = '* 첨부파일은 10MB이하만 등록가능합니다.'
              },
              error: function(args) {
                $('#result').html("<font color='red'>폼메일 발송 실패</font>");
                alert('발송실패.')
                // $('#frm').trigger("reset");
              },
            })
            //Ajax 전송 끝. eeeeeeeeeee
          }
        } else {
          return false;
        }

      }
    </script>
</body>

</html>

 

 

3. 발송용 smtp 정보 넣은 파일 생성

<?php

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

require 'src/Exception.php';
require 'src/PHPMailer.php';
require 'src/SMTP.php';

// Config
//=========================================================
$MAIL_MailTemplateFile = "./mail_template.html";
$MAIL_SMTP_Host = 'smtp.office365.com'; //아웃룩
$MAIL_SMTP_Username = '@@@'; //발송메일주소
$MAIL_SMTP_Password = '@@@'; //발송메일비번
$MAIL_FromEmail = '@@@'; //발송메일주소
$MAIL_FromEmailName = '@@@'; //이름
// $Q_TargetEmail = '@@@'; //받는사람 메일, 지금은 문의유형에 따라 받는사람 다르게 할거라서 아래에서 처리

//------------------------------------------------------

$H_Corp = $_REQUEST['H_Corp'];      //회사명
$H_Team = $_REQUEST['H_Team'];      //회사소속
$H_Name = $_REQUEST['H_Name'];      //고객명
$H_Email = $_REQUEST['H_Email'];    //이메일
$H_Tel = $_REQUEST['H_Tel'];      //연락처
$H_Deadline = $_REQUEST['H_Deadline'];      //제작기한


$H_Title = $_REQUEST['H_Title'];    //제목
$H_Content = $_REQUEST['H_Content'];  //내용
$H_file = $_FILES['H_File']; //첨부파일


$H_ContactType = $_REQUEST['H_ContactType'];  //문의유형
switch ($H_ContactType) {
  default:
  case '견적문의 및 상담':
    $Q_ContactType = '견적문의 및 상담';
    break;
  case 'A/S':
    $Q_ContactType = 'A/S';
    break;
  case '인사팀':
    $Q_ContactType = '인사팀';
    break;
}

$H_Budget = $_REQUEST['H_Budget'];              //제작 예산
switch ($H_Budget) {
  default:
  case '1':
    $Q_Budget = '100만원 미만';
    break;
  case '2':
    $Q_Budget = '100 - 300만원';
    break;
  case '3':
    $Q_Budget = '300 - 500만원';
    break;
  case '4':
    $Q_Budget = '500 - 1000만원';
    break;
  case '5':
    $Q_Budget = '1000 - 2000만원';
    break;
  case '6':
    $Q_Budget = '2000만원 초과';
    break;
}

$Q_Title = $H_Title;
if (!$Q_Title) $Q_Title = '[홈페이지 문의]'; // 타이틀이 없으면
$Q_CurrentTime = date('Y-m-d I H:i:s');
$Q_Content = '<pre style="font-size:14px; font-family:\'MalgunGothic\'; white-space: pre-wrap;">' . $H_Content . '</pre>';

// 발송 메일폼 로딩해서 문의 내용 입력
$handle = fopen($MAIL_MailTemplateFile, "r");
$template  = fread($handle, filesize($MAIL_MailTemplateFile));
fclose($handle);

$Q_Body = $template;
$Q_Body = str_replace('[CORP]', $H_Corp, $Q_Body);
$Q_Body = str_replace('[TEAM]', $H_Team, $Q_Body);
$Q_Body = str_replace('[NAME]', $H_Name, $Q_Body);
$Q_Body = str_replace('[EMAIL]', $H_Email, $Q_Body);
$Q_Body = str_replace('[DEADLINE]', $H_Deadline, $Q_Body);
$Q_Body = str_replace('[TEL]', $H_Tel, $Q_Body);
$Q_Body = str_replace('[CONTACTYPE]', $Q_ContactType, $Q_Body);
$Q_Body = str_replace('[BUDGET]', $Q_Budget, $Q_Body);
$Q_Body = str_replace('[TITLE]', $Q_Title, $Q_Body);
$Q_Body = str_replace('[CONTENT]', $Q_Content, $Q_Body);
$Q_Body = str_replace('[REGDATE]', $Q_CurrentTime, $Q_Body);
// $Q_Body = str_replace('[FILE]', $H_file['name'], $Q_Body);
$Q_Body = str_replace('[FILE]', $H_file['name'] != ""?$H_file['name']:'없음', $Q_Body);
// END

if (!is_null($H_Title)) {
  $mail = new PHPMailer(true);
  $mail->isSMTP();
  $mail->Host        = $MAIL_SMTP_Host;
  $mail->SMTPAuth    = true;
  $mail->Username    = $MAIL_SMTP_Username;
  $mail->Password    = $MAIL_SMTP_Password;
  $mail->SMTPSecure  = PHPMailer::ENCRYPTION_STARTTLS;
  $mail->Port        = 587;
  $mail->setFrom($MAIL_FromEmail, $MAIL_FromEmailName);
  // $mail->addAddress($Q_TargetEmail, 'TOjy');
  if ($H_ContactType == '인사팀') {            
    $mail->addAddress('@@@'); //받는사람1
  } else if ($H_ContactType == 'A/S') {
    $mail->addAddress('@@@'); //받는사람2
    $mail->addAddress('@@@'); //받는사람3(여러명일때)
  } else {
    $mail->addAddress('###'); //받는사람4
    $mail->addAddress('###'); //받는사람5(여러명일때)
  }
  if ($H_file['name'] != "") {
    $mail->addAttachment($H_file['tmp_name'], $H_file['name']);
  };

  $mail->isHTML(true);
  $mail->Subject     = $Q_Title;
  $mail->Body        = $Q_Body;
  $mail->CharSet = "UTF-8";
  $mail->Encoding = "base64";

  $mail->send();
  $send = 'Yes';
}
?>

 

 

4. 메일에서 보일 템플릿

<!-- S :: 홈페이지 문의하기 메일 발송 템플릿 -->
<div style="width: 100%; height: auto;">
  <h2 style="font-size: 18px; font-family:'MalgunGothic';">"[CONTACTYPE]" - @@@ 문의하기에서 [NAME] 님의 문의입니다. </h2>
  <table cellspacing="0" cellpadding="3" summary="고객 문의 등록 내용" style="border-top: 3px solid #333; width:100%; font-size: 12px; font-family:'MalgunGothic';">
      <tr style="border: 0px solid #E1E1E1; font-family:'MalgunGothic';">
        <th style="border-bottom: 1px solid #E1E1E1; width: 150px; background-color: #F7F7F7; scope:row; height:40px; padding: 5px 10px; font-family:'MalgunGothic'; white-space: nowrap;">문의 유형</th>
        <td style="border-bottom: 1px solid #E1E1E1; padding: 5px 10px; font-family:'MalgunGothic'; max-width: 500px;">[CONTACTYPE]</td>
      </tr>
      <tr style="border: 0px solid #E1E1E1; font-family:'MalgunGothic';">
        <th style="border-bottom: 1px solid #E1E1E1; width: 150px; background-color: #F7F7F7; scope:row; height:40px; padding: 5px 10px; font-family:'MalgunGothic'; white-space: nowrap;">고객명</th>
        <td style="border-bottom: 1px solid #E1E1E1; padding: 5px 10px; font-family:'MalgunGothic'; max-width: 500px;">[NAME]</td>
      </tr>
      <tr style="border: 0px solid #E1E1E1; font-family:'MalgunGothic';">
        <th style="border-bottom: 1px solid #E1E1E1; width: 150px; background-color: #F7F7F7; scope:row; height:40px; padding: 5px 10px; font-family:'MalgunGothic'; white-space: nowrap;">회사명</th>
        <td style="border-bottom: 1px solid #E1E1E1; padding: 5px 10px; font-family:'MalgunGothic'; max-width: 500px;">[CORP]</td>
      </tr>
      <tr style="border: 0px solid #E1E1E1; font-family:'MalgunGothic';">
        <th style="border-bottom: 1px solid #E1E1E1; width: 150px; background-color: #F7F7F7; scope:row; height:40px; padding: 5px 10px; font-family:'MalgunGothic'; white-space: nowrap;">연락처</th>
        <td style="border-bottom: 1px solid #E1E1E1; padding: 5px 10px; font-family:'MalgunGothic'; max-width: 500px;">[TEL]</td>
      </tr>
      <tr style="border: 0px solid #E1E1E1; font-family:'MalgunGothic';">
        <th style="border-bottom: 1px solid #E1E1E1; width: 150px; background-color: #F7F7F7; scope:row; height:40px; padding: 5px 10px; font-family:'MalgunGothic'; white-space: nowrap;">이메일</th>
        <td style="border-bottom: 1px solid #E1E1E1; padding: 5px 10px; font-family:'MalgunGothic'; max-width: 500px;">[EMAIL]</td>
      </tr>
      <!-- <tr>
        <th>회사소속</th>
        <td>[TEAM]]</td>
      </tr> -->
		  <!-- <tr>
        <th>제작기한</th>
        <td>[DEADLINE]</td>
      </tr>
		  <tr>
        <th>제작 예산</th>
        <td>[BUDGET]</td>
      </tr> -->
		  <tr style="border: 0px solid #E1E1E1; font-family:'MalgunGothic';">
        <th style="border-bottom: 1px solid #E1E1E1; width: 150px; background-color: #F7F7F7; scope:row; height:40px; padding: 5px 10px; font-family:'MalgunGothic'; white-space: nowrap;">문의 제목</th>
        <td style="border-bottom: 1px solid #E1E1E1; padding: 5px 10px; font-family:'MalgunGothic'; max-width: 500px;">[TITLE]</td>
      </tr>
      <tr style="border: 0px solid #E1E1E1; font-family:'MalgunGothic';">
        <th style="border-bottom: 1px solid #E1E1E1; width: 150px; background-color: #F7F7F7; scope:row; height:40px; padding: 5px 10px; font-family:'MalgunGothic'; white-space: nowrap;">문의 내용</th>
        <td style="border-bottom: 1px solid #E1E1E1; padding: 5px 10px; font-family:'MalgunGothic'; max-width: 500px;">[CONTENT]</td>
      </tr>
      <tr style="border: 0px solid #E1E1E1; font-family:'MalgunGothic';">
        <th style="border-bottom: 1px solid #E1E1E1; width: 150px; background-color: #F7F7F7; scope:row; height:40px; padding: 5px 10px; font-family:'MalgunGothic'; white-space: nowrap;">첨부파일</th>
        <td style="border-bottom: 1px solid #E1E1E1; padding: 5px 10px; font-family:'MalgunGothic'; max-width: 500px;">[FILE]</td>
      </tr>
      <tr style="border: 0px solid #E1E1E1; font-family:'MalgunGothic';">
        <th style="border-bottom: 1px solid #E1E1E1; width: 150px; background-color: #F7F7F7; scope:row; height:40px; padding: 5px 10px; font-family:'MalgunGothic'; white-space: nowrap;">문의 등록 시간</th>
        <td style="border-bottom: 1px solid #E1E1E1; padding: 5px 10px; font-family:'MalgunGothic'; max-width: 500px;">[REGDATE]</td>
      </tr>
    </table>
</div>
<!-- E :: 홈페이지 문의하기 메일 발송 템플릿 -->

 

 

5. 구글캡챠 v3 (2번에 이미 있는 내용, 기록)

<form>
	<input type="hidden" id="g-recaptcha" name="g-recaptcha"> <!-- 리캡챠 폼안에 넣어주기 -->
    <button type="submit" form="frm" value="보내기" class="btn-submit" onclick="$confirm();" name="button" disabled>
    	<span>문의하기</span>
    </button>
</form>

<script src='https://www.google.com/recaptcha/api.js?render=@@@'></script> <!-- @@@ 자리에 리캡챠 사이트키 넣어줌 -->
<script type="text/javascript">
    grecaptcha.ready(function() {
      grecaptcha.execute('@@@', { //@@@ 자리에 리캡챠 사이트키 넣어줌
        action: 'submit'
      }).then(function(token) {
        document.getElementById('g-recaptcha').value = token;
      });
    });
  </script>

 

 

일단 이정도만 기록,,

728x90