[함수] php에서 첨부파일이 포함된 메일 보내기 함수
로빈아빠
본문
/*=========================
함수 사용법
mail_fsend(받는사람,제목,메세지,추가해더,첨부할 파일)
참고 : 첨부할 파일은 메일이 발송되는 서버안에서의 파일임
참고 : 업로드와 연계해서 사용할 경우 알아서 업로드된 파일을 첨부해서 메일을 보냅니다.
언제나 '공대여자는 예쁘다'는 마음가짐이 있어야 사용하실 수 있습니다.
==========================*/
function mail_fsend($tos,$subject,$message='',$addtion_header='',$files=array()){
//첨부파일 가능용
/*
추천 해더설정
$addtion_header['content_type'] ='text/html';
$addtion_header['char_set']='UTF-8'; or $addtion_header['char_set']='EUC-KR';
*/
// $files: 는 서버내의 파일을 지목할 때 사용
//============================================== 기초 설정
$boundary = "----=b".md5(uniqid(time()));
$content_type= $addtion_header['content_type']; //기본내용형식 : 일반 text
if(empty($content_type)) $content_type='text/plain'; //기본문자셋 : utf-8
$char_set = $addtion_header['char_set'];
if(empty($char_set)) $char_set='UTF-8'; //기본문자셋 : utf-8
//=====================================================to 설정
if(is_string($tos)){
$to = $tos;
}else if(is_array($tos)){
$to = implode(', ',$tos);
}
//=====================================================subject 설정
if(empty($subject)){
$subject = 'No title '.date('Y-m-d H:i:s');
}
//$subject = '=?EUC-KR?B?'.base64_encode($subject).'?=';
$subject = '=?'.$char_set.'?B?'.base64_encode($subject).'?=';
//=====================================================해더 설정
$headers=array();
$headers['mime_version']='MIME-Version: 1.0';
//$headers['content_type']="Content-type: multipart/alternative; boundary=\"{$boundary}\"";
$headers['content_type']="Content-type: multipart/mixed; boundary=\"{$boundary}\"";
if(!empty($addtion_header['from'])){ $headers[]= "From: ".$addtion_header['from']; }
else{ $headers[]= "From: webmaster@{$_SERVER['SERVER_NAME';]}"; }
if(!empty($addtion_header['cc'])){ $headers[]= "cc: ".$addtion_header['cc']; }
if(!empty($addtion_header['bcc'])){ $headers[]= "Bcc: ".$addtion_header['bcc']; }
if(!empty($headers)){ $header = implode("\r\n",$headers)."\r\n"; }
else{ $header =''; }
//======================================================== 메세지 인코딩
$msg_content_type = "Content-type: {$content_type}; charset={$char_set}";
$msg = '';
$msg .= mail_fsend_enc_msg($boundary,$message,$msg_content_type); //본문 메세지 처리
//======================================================== 첨부파일 인코딩
if(!is_array($files)){$files=array($files);}//강제로 배열로 만든다.
for($i =0,$m=count($files);$i<$m;$i++){
$msg .= mail_fsend_enc_file($boundary,$files[$i]); //첨부파일 처리
}
//======================================================== 업로드 되는 첨부파일 인코딩
if(!empty($_FILES)){
foreach($_FILES as $key=> $value){ $t = $key; break; }
$t_files = $_FILES[$t]['tmp_name'];
$t_filenames = $_FILES[$t]['name'];
$t_error = $_FILES[$t]['error'];
if(!is_array($t_files)){$t_files=array($t_files);}
if(!is_array($t_filenames)){$t_filenames=array($t_filenames);}
if(!is_array($t_error)){$t_error=array($t_error);}
for($i =0,$m=count($t_files);$i<$m;$i++){
if($t_error[$i]==0){
$msg .= mail_fsend_enc_file($boundary,$t_files[$i],$t_filenames[$i]); //첨부파일 처리
}
}
}
//========================================================= 메세지 닫기
$msg .='--'.$boundary."--";
//===================================================== 메일 보내기
//===================================================== 릴레이션 설정이 필요한 경우는 알아서...
$result = mail ($to,$subject,$msg,$header);
return $result;
}
function mail_fsend_enc_msg($boundary,$msg='',$content_type='Content-type: text/plain; charset=utf-8'){
//본문문자열 인코딩
$re_str = '';
$re_str = '--'.$boundary."\r\n"; //바운드리 설정
$re_str .= $content_type."\r\n";
$re_str .= 'Content-Transfer-Encoding: base64'."\r\n"."\r\n";
// RFC 2045 에 맞게 $data를 형식화
$new_msg = chunk_split(base64_encode($msg));
$re_str .=$new_msg."\r\n";
return $re_str;
}
function mail_fsend_enc_file($boundary,$file,$filename=''){
//첨부파일 인코딩
$content_type = 'Content-Type: application/octet-stream; charset=UTF8';
$re_str = '';
$re_str = '--'.$boundary."\r\n"; //바운드리 설정
$re_str .= $content_type."\r\n";
$re_str .= 'Content-Transfer-Encoding: base64'."\r\n";
if(strlen($filename)==0){ $filename = basename($file); }
$re_str .= "Content-Disposition: attachment; filename=\"".'=?UTF-8?B?'.base64_encode($filename).'?='."\""."\r\n"."\r\n";
// RFC 2045 에 맞게 $data를 형식화
$fp = @fopen($file, "r");
if($fp) { $msg = fread($fp, filesize($file)); fclose($fp); }
$new_msg = chunk_split(base64_encode($msg));
$re_str .=$new_msg."\r\n";
return $re_str;
}
//-----------------------------------------------------------------------
함수 사용법
---------------------=---------------------------
솔찍히 이건 함수를 사용하시라는게 아니라 참고하시라고 올려놓는 겁니다.
메일의 경우 여러 규격이 있지만 그중에서 가장 많이 사용되는 규격중에서
첨부파일을 처리하는 방법은 RFC 2045 입니다.
그 규격은 multipart/mixed 와 boundary , base64_encode 가 요점입니다.
==========================================
멀티파트로 보낼 경우 기본적 구조
# 해더
Content-type: multipart/mixed; boundary="123456" 를 선언
# 본문
--123456 (\r\n 으로 줄바꿈)
Content-type: text/plain; charset=utf-8(\r\n)
Content-Transfer-Encoding: base64(\r\n)
(\r\n)
chunk_split(base64_encode(메세지));(\r\n)
--123456 (\r\n 으로 줄바꿈)
Content-type: application/octet-stream; charset=utf-8(\r\n)
Content-Transfer-Encoding: base64(\r\n)
Content-Disposition: attachment; filename=파일이름(\r\n)
(\r\n)
chunk_split(base64_encode(메일내용));(\r\n)
--123456--
-> 설명
#해더에서 Content-type 를 multipart/mixed 로 선언
바운더리로 사용할 123456 를 선언
#본문에서
'--123456' 으로 바운더리를 적어서 그부분이 하나의 파트라는 것을 표시
바로밑에 content-type 등을 적고 \r\n으로 줄바꿈
본메세지와는 \r\n으로 한줄이 더 생기도록 함
본메세지는 chunk_split(base64_encode($msg));(\r\n) 로 삽입
(chunk_split : RFC 2045형식에 맞도록 문자열을 줄바꿈 해줍니다.)
(base64_encode : 메일의 기본은 64 인코딩입니다.)
이로 일반 메세지 부분은 끝
또다시 '--123456' 으로 바운더리를 적어서 그부분이 하나의 파트라는 것을 표시
파일을 첨부할 경우
Content-type: application/octet-stream; charset=utf-8(\r\n)
Content-Transfer-Encoding: base64(\r\n)
Content-Disposition: attachment; filename=파일이름(\r\n)
(\r\n)
라고 삽입
본메세지는 파일안의 내용으로
chunk_split(base64_encode(파일안의 내용));(\r\n) 를 삽입
마지막으로
'--123456--' 으로 끝이라고 표시
====================-=============
설명이 이상한것 같은데
어쨌든 중요한건 해더에 선언하는 content-type과
부분을 나누는 boundary 입니다.
이것만 기억하면 간단하게 첨부파일 메일 보내기는 성공하실 수 있습니다.
너무 어수선한것 같은데...
칼솜님의 요청으로 후다닥 적었습니다.
출처 PHPSCHOOL-공대여자는예쁘다님
함수 사용법
mail_fsend(받는사람,제목,메세지,추가해더,첨부할 파일)
참고 : 첨부할 파일은 메일이 발송되는 서버안에서의 파일임
참고 : 업로드와 연계해서 사용할 경우 알아서 업로드된 파일을 첨부해서 메일을 보냅니다.
언제나 '공대여자는 예쁘다'는 마음가짐이 있어야 사용하실 수 있습니다.
==========================*/
function mail_fsend($tos,$subject,$message='',$addtion_header='',$files=array()){
//첨부파일 가능용
/*
추천 해더설정
$addtion_header['content_type'] ='text/html';
$addtion_header['char_set']='UTF-8'; or $addtion_header['char_set']='EUC-KR';
*/
// $files: 는 서버내의 파일을 지목할 때 사용
//============================================== 기초 설정
$boundary = "----=b".md5(uniqid(time()));
$content_type= $addtion_header['content_type']; //기본내용형식 : 일반 text
if(empty($content_type)) $content_type='text/plain'; //기본문자셋 : utf-8
$char_set = $addtion_header['char_set'];
if(empty($char_set)) $char_set='UTF-8'; //기본문자셋 : utf-8
//=====================================================to 설정
if(is_string($tos)){
$to = $tos;
}else if(is_array($tos)){
$to = implode(', ',$tos);
}
//=====================================================subject 설정
if(empty($subject)){
$subject = 'No title '.date('Y-m-d H:i:s');
}
//$subject = '=?EUC-KR?B?'.base64_encode($subject).'?=';
$subject = '=?'.$char_set.'?B?'.base64_encode($subject).'?=';
//=====================================================해더 설정
$headers=array();
$headers['mime_version']='MIME-Version: 1.0';
//$headers['content_type']="Content-type: multipart/alternative; boundary=\"{$boundary}\"";
$headers['content_type']="Content-type: multipart/mixed; boundary=\"{$boundary}\"";
if(!empty($addtion_header['from'])){ $headers[]= "From: ".$addtion_header['from']; }
else{ $headers[]= "From: webmaster@{$_SERVER['SERVER_NAME';]}"; }
if(!empty($addtion_header['cc'])){ $headers[]= "cc: ".$addtion_header['cc']; }
if(!empty($addtion_header['bcc'])){ $headers[]= "Bcc: ".$addtion_header['bcc']; }
if(!empty($headers)){ $header = implode("\r\n",$headers)."\r\n"; }
else{ $header =''; }
//======================================================== 메세지 인코딩
$msg_content_type = "Content-type: {$content_type}; charset={$char_set}";
$msg = '';
$msg .= mail_fsend_enc_msg($boundary,$message,$msg_content_type); //본문 메세지 처리
//======================================================== 첨부파일 인코딩
if(!is_array($files)){$files=array($files);}//강제로 배열로 만든다.
for($i =0,$m=count($files);$i<$m;$i++){
$msg .= mail_fsend_enc_file($boundary,$files[$i]); //첨부파일 처리
}
//======================================================== 업로드 되는 첨부파일 인코딩
if(!empty($_FILES)){
foreach($_FILES as $key=> $value){ $t = $key; break; }
$t_files = $_FILES[$t]['tmp_name'];
$t_filenames = $_FILES[$t]['name'];
$t_error = $_FILES[$t]['error'];
if(!is_array($t_files)){$t_files=array($t_files);}
if(!is_array($t_filenames)){$t_filenames=array($t_filenames);}
if(!is_array($t_error)){$t_error=array($t_error);}
for($i =0,$m=count($t_files);$i<$m;$i++){
if($t_error[$i]==0){
$msg .= mail_fsend_enc_file($boundary,$t_files[$i],$t_filenames[$i]); //첨부파일 처리
}
}
}
//========================================================= 메세지 닫기
$msg .='--'.$boundary."--";
//===================================================== 메일 보내기
//===================================================== 릴레이션 설정이 필요한 경우는 알아서...
$result = mail ($to,$subject,$msg,$header);
return $result;
}
function mail_fsend_enc_msg($boundary,$msg='',$content_type='Content-type: text/plain; charset=utf-8'){
//본문문자열 인코딩
$re_str = '';
$re_str = '--'.$boundary."\r\n"; //바운드리 설정
$re_str .= $content_type."\r\n";
$re_str .= 'Content-Transfer-Encoding: base64'."\r\n"."\r\n";
// RFC 2045 에 맞게 $data를 형식화
$new_msg = chunk_split(base64_encode($msg));
$re_str .=$new_msg."\r\n";
return $re_str;
}
function mail_fsend_enc_file($boundary,$file,$filename=''){
//첨부파일 인코딩
$content_type = 'Content-Type: application/octet-stream; charset=UTF8';
$re_str = '';
$re_str = '--'.$boundary."\r\n"; //바운드리 설정
$re_str .= $content_type."\r\n";
$re_str .= 'Content-Transfer-Encoding: base64'."\r\n";
if(strlen($filename)==0){ $filename = basename($file); }
$re_str .= "Content-Disposition: attachment; filename=\"".'=?UTF-8?B?'.base64_encode($filename).'?='."\""."\r\n"."\r\n";
// RFC 2045 에 맞게 $data를 형식화
$fp = @fopen($file, "r");
if($fp) { $msg = fread($fp, filesize($file)); fclose($fp); }
$new_msg = chunk_split(base64_encode($msg));
$re_str .=$new_msg."\r\n";
return $re_str;
}
//-----------------------------------------------------------------------
함수 사용법
---------------------=---------------------------
솔찍히 이건 함수를 사용하시라는게 아니라 참고하시라고 올려놓는 겁니다.
메일의 경우 여러 규격이 있지만 그중에서 가장 많이 사용되는 규격중에서
첨부파일을 처리하는 방법은 RFC 2045 입니다.
그 규격은 multipart/mixed 와 boundary , base64_encode 가 요점입니다.
==========================================
멀티파트로 보낼 경우 기본적 구조
# 해더
Content-type: multipart/mixed; boundary="123456" 를 선언
# 본문
--123456 (\r\n 으로 줄바꿈)
Content-type: text/plain; charset=utf-8(\r\n)
Content-Transfer-Encoding: base64(\r\n)
(\r\n)
chunk_split(base64_encode(메세지));(\r\n)
--123456 (\r\n 으로 줄바꿈)
Content-type: application/octet-stream; charset=utf-8(\r\n)
Content-Transfer-Encoding: base64(\r\n)
Content-Disposition: attachment; filename=파일이름(\r\n)
(\r\n)
chunk_split(base64_encode(메일내용));(\r\n)
--123456--
-> 설명
#해더에서 Content-type 를 multipart/mixed 로 선언
바운더리로 사용할 123456 를 선언
#본문에서
'--123456' 으로 바운더리를 적어서 그부분이 하나의 파트라는 것을 표시
바로밑에 content-type 등을 적고 \r\n으로 줄바꿈
본메세지와는 \r\n으로 한줄이 더 생기도록 함
본메세지는 chunk_split(base64_encode($msg));(\r\n) 로 삽입
(chunk_split : RFC 2045형식에 맞도록 문자열을 줄바꿈 해줍니다.)
(base64_encode : 메일의 기본은 64 인코딩입니다.)
이로 일반 메세지 부분은 끝
또다시 '--123456' 으로 바운더리를 적어서 그부분이 하나의 파트라는 것을 표시
파일을 첨부할 경우
Content-type: application/octet-stream; charset=utf-8(\r\n)
Content-Transfer-Encoding: base64(\r\n)
Content-Disposition: attachment; filename=파일이름(\r\n)
(\r\n)
라고 삽입
본메세지는 파일안의 내용으로
chunk_split(base64_encode(파일안의 내용));(\r\n) 를 삽입
마지막으로
'--123456--' 으로 끝이라고 표시
====================-=============
설명이 이상한것 같은데
어쨌든 중요한건 해더에 선언하는 content-type과
부분을 나누는 boundary 입니다.
이것만 기억하면 간단하게 첨부파일 메일 보내기는 성공하실 수 있습니다.
너무 어수선한것 같은데...
칼솜님의 요청으로 후다닥 적었습니다.
출처 PHPSCHOOL-공대여자는예쁘다님
댓글목록
등록된 댓글이 없습니다.