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템플릿을 만들어줬습니다.
능력자분들은 좀 더 예쁘게 꾸밀 수도 있겠죠 (__);
저는 딱 이렇게 표로만 나옵니다.
다운로드
저도... 기본 소스 정도는 남겨놔야 추후 비슷한 작업이 있을 때 가져다 쓸 수 있으므로 작업한 소스 올려놓습니다.
몇년에 한번씩 할까 말까 하지만 정작 필요할 때 삽질하게 되네요ㅠㅠ
출처
메일 발송 HTML 템플릿작성방법
https://beautifulhill.tistory.com/8
jQuery 첨부파일 용량 체크 방법
https://tychejin.tistory.com/305
메일 발송 제목 변수 붙이기, 문자열 합치기 방법
https://blog.naver.com/PostView.nhn?blogId=reviewer__&logNo=221413200890
#폼메일