CMS솔루션마켓, 이온디 - 워드프레스, 라이믹스, 카페24, 그누보드, 엑셀

블로그

1. Sendmail.php 

<?php
/* 
=================================================================================
 + 안내 : 이 파일은 아래의 웹싸이트 자료를 참고로 수정하였음을 알려드립니다.
 + 출처 : http://redqueen-textcube.blogspot.kr/2011/07/php-class.html
 + 제작자 : 하근호(hopegiver@korea.com)
=================================================================================
 + 파일명 : Sendmail.php
 + 수정일 : 2015-06-04/2015-06-04(최종수정일)
 + 수정자 : Redinfo (webmaster@redinfo.co.kr)
 + 기타   : (가이드 URL) http://b.redinfo.co.kr/87
            (싸이트 URL) http://b.redinfo.co.kr
=================================================================================
*/

class Sendmail {
    /* smtp 의 호스트 설정 : 아래는 gmail 일경우 */
    var $host="ssl://smtp.gmail.com";
 /* smtp 계정 아이디 입력 */
    var $smtp_id="eond@eond.com";
    /* smtp 계정 비밀번호 입력 */
 var $smtp_pw="password";
 
    /* 디버그모드 - 활성 :1, 비활성 : 0; */
    var $debug = 1; 
 /* 문자 인코딩 종류 설정*/
    var $charset="UTF-8";
 /* 메일의 기본 타입을 설정 */
    var $ctype="text/plain";


 /* 아래 3개의 변수는 수정 금지 */
    var $fp;
    var $lastmsg;
    var $parts=array();

 
 /* 기본설정대신 초기화 할 값이 있다면 클래스 초기화시 배열로 값을넘겨준다. */
    function Sendmail($data=false) {

  if($data!=false)
  {
   if(is_array($data)){
     /* 각각 배열의 정보는 기본설정 변수명과 같으니 그곳을 참고하길 바란다 */
     $this->host = !empty($data['host'])?$data['host']:$this->host;
     $this->smtp_id = !empty($data['smtp_id'])?$data['smtp_id']:$this->smtp_id;
     $this->smtp_pw = !empty($data['smtp_pw'])?$data['smtp_pw']:$this->smtp_pw;
     $this->debug = !empty($data['debug'])?$data['debug']:$this->debug; 
     $this->charset = !empty($data['charset'])?$data['charset']:$this->charset;
     $this->ctype = !empty($data['ctype'])?$data['ctype']:$this->ctype;
   }
  }
    }

     /*  smtp 통신을 한다. */
    function dialogue($code, $cmd) {
        fputs($this->fp, $cmd."\r\n");
        $line = fgets($this->fp, 1024);
        preg_match("/^([0-9]+).(.*)$/", $line, $matches);
        $this->lastmsg = $matches[0];
        if($this->debug) {
           echo htmlspecialchars($cmd)."
".$this->lastmsg."
";
            flush();
        }
        if($matches[1] != $code) return false;
        return true;
    }
     /*   smptp 서버에 접속을 한다. */
    function connect($host='') {
        if($this->debug) {
            echo "SMTP(".$host.") Connecting...";
            flush();
        }
        if(!$host) $host = $this->host;
        if(!$this->fp = fsockopen($host, 465, $errno, $errstr, 10)) {
            $this->lastmsg = "SMTP(".$host.") 서버접속에 실패했습니다.[".$errno.":".$errstr."]";
            return false;
        }
        $line = fgets($this->fp, 1024);
        preg_match("/^([0-9]+).(.*)$/", $line, $matches);
        $this->lastmsg = $matches[0];
        if($matches[1] != "220") return false;
        if($this->debug) {
            echo $this->lastmsg."
";
            flush();
        }
        $this->dialogue(250, "HELO phpmail");
        return true;
    }
     /*  stmp 서버와의 접속을 끊는다. */
    function close() {
        $this->dialogue(221, "QUIT");
        fclose($this->fp);
        return true;
    }
     /*  메시지를 보낸다. */
    function smtp_send($email, $from, $data,$cc_mail,$bcc_mail,$rel_to=false) {
  
  $id = $this->smtp_id;
        $pwd = $this->smtp_pw;

  
   
  /* 이메일 형식 검사 구간*/
        if(!$mail_from = $this->get_email($from)) return false;
        if(!$rcpt_to = $this->get_email($email)) return false;   
  
 
  
  /* smtp  검사 구간 */
  if(!$this->dialogue(334, "AUTH LOGIN")) { return false; }
        if(!$this->dialogue(334, base64_encode($id)))  return false;
        if(!$this->dialogue(235, base64_encode($pwd)))  return false;
        if(!$this->dialogue(250, "MAIL FROM:".$mail_from)) return false;
        if(!$this->dialogue(250, "RCPT TO:".$rcpt_to)) {
            $this->dialogue(250, "RCPT TO:");
            $this->dialogue(354, "DATA");  
            $this->dialogue(250, ".");
            return false;
        }
  
  if($rel_to==false){ $rel_to=$email;}
  
  
  $this->dialogue(354, "DATA");
        $mime = "Message-ID: <".$this->get_message_id().">\r\n";
        $mime .= "From: ".$from."\r\n";
        $mime .= "To: ".$rel_to."\r\n";
       
  /* CC 메일 이 있을경우 */
        if($cc_mail!=false){

    $mime .= "Cc: ".$cc_mail. "\r\n";
    
  }
        /* BCC 메일 이 있을경우 */
  if($bcc_mail!=false) $mime .= "Bcc: ".$bcc_mail. "\r\n";
  
  
        
        fputs($this->fp, $mime);
        fputs($this->fp, $data);
        $this->dialogue(250, ".");
  
  
  
 
    }
    /* Message ID 를 얻는다. */
    function get_message_id() {
        $id = date("YmdHis",time());
        mt_srand((float) microtime() * 1000000);
        $randval = mt_rand();
        $id .= $randval."@phpmail";
        return $id;
    }
    /* Boundary 값을 얻는다. */
    function get_boundary() {
        $uniqchr = uniqid(time());
        $one = strtoupper($uniqchr[0]);
        $two = strtoupper(substr($uniqchr,0,8));
        $three = strtoupper(substr(strrev($uniqchr),0,8));
        return "----=_NextPart_000_000${one}_${two}.${three}";
    }
 
    /* 첨부파일이 있을 경우 이 함수를 이용해 파일을 첨부한다. */
    function attach($path, $name="", $ctype="application/octet-stream") {
        if(is_file($path)) {
            $fp = fopen($path, "r");
            $message = fread($fp, filesize($path));
            fclose($fp);
            $this->parts[] = array ("ctype" => $ctype, "message" => $message, "name" => $name);
  
   
        } else return false;
    }
     /*  Multipart 메시지를 생성시킨다. */
    function build_message($part) {
        $msg = "Content-Type: ".$part['ctype'];
        if($part['name']) $msg .= "; name=\"".$part['name']."\"";
        $msg .= "\r\nContent-Transfer-Encoding: base64\r\n";
        $msg .= "Content-Disposition: attachment; filename=\"".$part['name']."\"\r\n\r\n";
        $msg .= chunk_split(base64_encode($part['message']));
        return $msg;
    }
 
    /*  SMTP에 보낼 DATA를 생성시킨다. */
    function build_data($subject, $body) {
        $boundary = $this->get_boundary();
        $attcnt = sizeof($this->parts);
        $mime= "Subject: ".$subject."\r\n";
        $mime .= "Date: ".date ("D, j M Y H:i:s T",time())."\r\n";
        $mime .= "MIME-Version: 1.0\r\n";
        if($attcnt > 0) {
            $mime .= "Content-Type: multipart/mixed; boundary=\"".$boundary."\"\r\n\r\n".
                "This is a multi-part message in MIME format.\r\n\r\n";
            $mime .= "--".$boundary."\r\n";
        }
        $mime .= "Content-Type: ".$this->ctype."; charset=\"".$this->charset."\"\r\n".
            "Content-Transfer-Encoding: base64\r\n\r\n" . chunk_split(base64_encode($body));
       
        if($attcnt > 0) {
            $mime .= "\r\n\r\n--".$boundary;
            for($i=0; $i<$attcnt; $i++) {
                $mime .= "\r\n".$this->build_message($this->parts[$i])."\r\n\r\n--".$boundary;
            }
            $mime .= "--\r\n";
        }

        return $mime;
    }
    /* MX 값을 찾는다. */
    function get_mx_server($email) {
        
        if(!preg_match("/([\._0-9a-zA-Z-]+)@([0-9a-zA-Z-]+\.[a-zA-Z\.]+)/", $email, $matches)) return false;
        getmxrr($matches[2], $host);
        if(!$host) $host[0] = $matches[2];
        return $host;
    }
     /*  이메일의 형식이 맞는지 체크한다. */
    function get_email($email) {
        if(!preg_match("/([\._0-9a-zA-Z-]+)@([0-9a-zA-Z-]+\.[a-zA-Z\.]+)/", $email, $matches)) return false;
        return "<".$matches[0].">";
    }
    /* 메일을 전송한다. */
    function send_mail($to, $from, $subject, $body,$cc_mail=false,$bcc_mail=false) {
  
  
  $from.=" <".$this->smtp_id.">";
      
  if(!is_array($to)){
   $rel_to=$to;
   $to = explode(",",$to);  
  }
  else{  
   $rel_to=implode(',',$to);
  }
   
   
        $data = $this->build_data($subject, $body);
        if($this->host == "auto") {
            foreach($to as $email) {
                if($host = $this->get_mx_server($email)) {
                    for($i=0, $max=count($host); $i<$max; $i++) {
                        if($conn = $this->connect($host[$i])) break;
                    }
                    if($conn) {
                        $this->smtp_send($email, $from, $data,$cc_mail,$bcc_mail);
                        $this->close();
                    }
                }
            }
        } else {
          
      
     
            foreach($to as $key=>$email){
    $this->connect($this->host);
    $this->smtp_send($email, $from, $data,$cc_mail,$bcc_mail,$rel_to);
    $this->close();
   }
   
   if($cc_mail!=false){
   $this->cc_email($rel_to,$from,$data,$cc_mail,$bcc_mail); 
   }
   if($bcc_mail!=false){
   $this->bcc_email($rel_to,$from,$data,$cc_mail,$bcc_mail);   
   }
        }
    }
 
 function cc_email($rel_to,$from,$data,$cc_mail,$bcc_mail)
 {
  if(!is_array($cc_mail)) $cc = explode(",",$cc_mail);
  
  foreach($cc as $email){   
    $this->connect($this->host);
    $this->smtp_send($email, $from, $data,$cc_mail,$bcc_mail,$rel_to);
    $this->close(); 
  }
 }
 function bcc_email($rel_to,$from,$data,$cc_mail,$bcc_mail){

  if(!is_array($bcc_mail)) $bcc = explode(",",$bcc_mail);
  
  foreach($bcc as $email){  
    $this->connect($this->host);
    $this->smtp_send($email, $from, $data,$cc_mail,$bcc_mail,$rel_to);
    $this->close(); 
  }
  
 }
}
?>

기본 발송 클래스는 수정할 게 없습니다.


2. 메일발송 프로그램

<?php
/* 클래스 파일 로드 */
include "Sendmail.php";

/*
 + host       : smtp 호스트 주소
 + smtp_id    : smtp 계정 아이디
 + smtp_pw    : smtp 계정 비번
 + debug      : 디버그표시기능 [1 : 활성 0 : 비활성]
 + charset    : 문자 인코딩
 + ctype      : 메일 컨텐츠의 타입
*/

$config=array(
  'host'=>'ssl://smtp.naver.com', // ssl://smtp.gmail.com
  'smtp_id'=>'id@naver.com',
  'smtp_pw'=>'password',
  'debug'=>0,
  'charset'=>'utf-8',
  'ctype'=>'text/html'
);
$sendmail = new Sendmail($config);


/*
 + $path   : 파일의 절대 경로
 + $name   : 파일의 이름을 설정
 + $ctype  : 메일 컨텐츠 타입 (옵션값으로 기본값은 application/octet-stream 이다 )
*/
//$path="test3.zip";
//$name="test3.zip";

$path = $_POST['path'];
$name = $path;
$ctype="application/octet-stream";

/* 첨부파일 추가 */
$sendmail->attach($path,$name,$ctype);

/*
 + $to       : 받는사람 메일주소 ( ex. $to="hong <hgd@example.com>" 으로도 가능)
 + $from     : 보내는사람 이름
 + $subject  : 메일 제목
 + $body     : 메일 내용
 + $cc_mail  : Cc 메일 있을경우 (옵션값으로 생략가능)
 + $bcc_mail : Bcc 메일이 있을경우 (옵션값으로 생략가능)
*/
//$to="eond@eond.com";
//$from="Master";
//$subject="첨부파일이 있습니다.";
//$body="첨부파일이 추가되었습니다.";
$to = $_POST['to'];
$from = $_POST['from'];
$subject = $_POST['name'] ."님 " . $_POST['subject']."입니다.";

$fp = fopen('template.html',"r");
$message = fread($fp,filesize('template.html'));

$name = $_POST['name'];
$position = $_POST['position'];
$phone = $_POST['phone'];
$email = $_POST['email'];
$project = $_POST['project'];
$deposit = $_POST['deposit'];
$deadline = $_POST['deadline'];
$desc = $_POST['desc'];
$message = str_replace('{name}', $name, $message);
$message = str_replace('{position}', $position, $message);
$message = str_replace('{phone}', $phone, $message);
$message = str_replace('{email}', $email, $message);
$message = str_replace('{project}', $project, $message);
$message = str_replace('{deposit}', $deposit, $message);
$message = str_replace('{deadline}', $deadline, $message);
$message = str_replace('{desc}', $desc, $message);
echo $message;

// $body = $_POST[body];
//이름
//직책
//전화번호
//이메일
//
//프로젝트 종류
//대략적인예산
//보고서최종기한
//프로젝트 설명
$cc_email="";
$bcc_mail="";


/* 메일 보내기 */
$sendmail->send_mail($to, $from, $subject, $message,$cc_mail,$bcc_mail)
?>

index.html에서 메일을 보낼 때 사용되는 php 코드입니다. $config 부분에 smtp 발송 정보를 입력합니다.
압축프로그램에서 js, exe 확장자가 들어있는 경우는 메일 발송이 안되네요.


1) 체크박스 여러개를 하고 싶을 경우

$project = implode(',',$_POST['project']);

2) 본문 줄바꿈 처리하고 싶을 경우

$message = str_replace('{desc}', nl2br($desc), $message);

3) XE레이아웃으로 제작시 첨부파일이 들어가지 않는 문제

XE 레이아웃에서 사용하려고 레이아웃 폴더 하위에 이 파일들을 넣었는데, 파일 첨부가 안되네요.
form action="/mail/mail.php" 이렇게 별도 최상위 디렉토리에서 mail.php, sendmail.php 을 넣어두고 동작했을 때는
정상적으로 첨부파일이 메일에 첨부가 됩니다.

4) 파일 형식이 zip 외에 ppt, hwp 이런건 첨부가 안되네요 @_@ 도와주세요..


3. index.html

<!doctype html>
<html lang="ko">
<head>
    <meta 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">
    <title>Document</title>
    <script
            src="https://code.jquery.com/jquery-3.6.0.min.js"
            integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
            crossorigin="anonymous"></script>
</head>
<body>
<form action="mail.php" method="post">
    <input type="email" name="to" placeholder="받는 사람 메일 주소" value="ja14k@naver.com">
    <input type="email" name="from" placeholder="보내는 사람 메일 주소" value="ja14k@naver.com">
    <input type="text" name="subject" placeholder="제목" value="견적 요청">
    <!--<input type="text" name="body" placeholder="본문내용" value="미리 입력된 본문 내용">-->
    <input type="file" name="path" placeholder="첨부파일" id="file">
    <div class="file-size">

    </div>
    <script>
        $("#file").change(function(){
            if($("#file").val() != ""){
                var maxSize = 10 * 1024 * 1024; // 10MB
                var fileSize = $("#file")[0].files[0].size;
                if(fileSize > maxSize){
                    alert("첨부파일 사이즈는 10MB 이내로 등록 가능합니다.");
                    $("#file").val("");
                    return false;
                }
            }
        });
    </script>
    <pre>
    이름
    <input type="text" name="name">
    직책
    <input type="text" name="position">
    전화번호
    <input type="text" name="phone">
    이메일
    <input type="text" name="email">
    프로젝트 종류
    <input type="checkbox" name="project" value="프로젝트1">
    <input type="checkbox" name="project" value="프로젝트2">
    대략적인예산
    <input type="checkbox" name="deposit" value="에산1">
    <input type="checkbox" name="deposit" value="에산2">
    보고서최종기한
    <input type="text" name="deadline">
    프로젝트 설명
    <textarea name="desc" id="" cols="30" rows="10"></textarea>
    </pre>
    <div>
        <input type="submit" value="보내기">
    </div>
</form>
</body>
</html>

이걸 어떻게 작성해야하나 몰라서, 2번, 3번 파일 작성하는데 애먹은 거 같네요.
최종적으로는 아래와 같이 디자인을 입혀야 합니다. ;ㅁ;


4. template.html

<!doctype html>
<html lang="ko">
<head>
    <meta 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">
    <title>견적요청</title>
    <style type="text/css">
      table tr td{
        border: 1px solid #5da399;
        text-align: center;
        padding: 10px;
      }
    </style>
</head>
<body>
<table>
    <tr>
        <td>1. 이름</td>
        <td>{name}</td>
    </tr>
    <tr>
        <td>2. 직책</td>
        <td>{position}</td>
    </tr>
    <tr>
        <td>3. 전화번호</td>
        <td>{phone}</td>
    </tr>
    <tr>
        <td>4. 이메일</td>
        <td>{email}</td>
    </tr>
    <tr>
        <td>5. 프로젝트 종류</td>
        <td>{project}</td>
    </tr>
    <tr>
        <td>6. 대략적인 예산</td>
        <td>{deposit}</td>
    </tr>
    <tr>
        <td>7. 보고서 최종기한</td>
        <td>{deadline}</td>
    </tr>
    <tr>
        <td>8. 프로젝트 설명</td>
        <td>{desc}</td>
    </tr>
</table>
</body>
</html>

메일을 받았을 때 어떤 형태로 보낼지 HTML템플릿을 만들어줬습니다.
능력자분들은 좀 더 예쁘게 꾸밀 수도 있겠죠 (__);

저는 딱 이렇게 표로만 나옵니다. 


다운로드

Sendmail.zip

저도... 기본 소스 정도는 남겨놔야 추후 비슷한 작업이 있을 때 가져다 쓸 수 있으므로 작업한 소스 올려놓습니다.
몇년에 한번씩 할까 말까 하지만 정작 필요할 때 삽질하게 되네요ㅠㅠ


출처

기본코드
http://b.redinfo.co.kr/87

메일 발송 HTML 템플릿작성방법
https://beautifulhill.tistory.com/8

jQuery 첨부파일 용량 체크 방법
https://tychejin.tistory.com/305

메일 발송 제목 변수 붙이기, 문자열 합치기 방법
https://blog.naver.com/PostView.nhn?blogId=reviewer__&logNo=221413200890


#폼메일