1. 메일 확인
2. 메일 조회
3. 메일 지우기
4. 메일 보내기

다섯번째 강좌 시간입니다. 오늘은 메일을 삭제하는 것입니다. 지난번 메일 확인 강좌에서 나온 리스트 보기에서 삭제할 메일을 선택한후 이를 삭제하는 부분이 되겠습니다..

소스를 보죠..

mail_cmd.php

<?
include ("mail_lib.php");

$cmd = $CMD;
$box = $BOX;
$part_no = $PART_NO;
if($box == "") $box = "INBOX";
$login = "userid";
$pass = "pwd";
$C_DOMAIN = "hagopa.co.kr";

$mailstream = imap_open("{" . $C_DOMAIN . ":143}" . $box, $login, $pass);
if ($mailstream == 0) {
echo "Error!
";
exit;
}

switch($cmd) {
case "del":
for($i=0;$i<count($NO);$i++) {
$result = imap_delete($mailstream, $NO[$i]);
// 해당 번호의 메일에 삭제 표시를 합니다. 즉 위 함수는 실제
// 삭제시키는 함수가 아니라는 거죠..

if(!$result) {
echo "삭제실패";
imap_close($mailstream);
exit;
}
imap_expunge($mailstream);
// 위에서 삭제 표시를 한 메일을 삭제하는 명령을 수행합니다.
// 이 함수가 호출 되지 않고 루틴이 끝나면 삭제되지 않습니다.
}
break;
}

imap_close($mailstream);
RedirectTarget("mail_list.php?BOX=".$box, "");
?>
, .

1. 메일 확인
2. 메일 조회
3. 메일 지우기
4. 메일 보내기

단지 지난 번엔 하나의 메일에 있는 boundary로 나뉘어진 여러 part들을 분석해서 화면에 출력하는 것을 했고 이번엔 그중 첨부파일에 대한 part 하나를 다운로드시키는 부분이 되겠습니다.

소스를 보죠..

mail_down.php

<?
// 지난번 mail_detail.php에 있는 printbody 함수와 거의 같습니다..
// 다른 부분만 설명하죠..


function printbody($mailstream, $MSG_NO, $numpart, $encode, $mime, $file_name) {
$val = imap_fetchbody($mailstream, $MSG_NO, (string)($numpart+1), FT_UID);

switch($encode) {
case 0: // 7bit
break;
case 1: // 8bit
$val = imap_base64(imap_binary(imap_qprint(imap_8bit($val))));
break;
case 2: // binary
$val = imap_base64(imap_binary($val));
break;
case 3: // base64
$val = imap_base64($val);
break;
case 4: // quoted-print
$val = imap_base64(imap_binary(imap_qprint($val)));
break;
case 5: // other
echo "알수없는 Encoding 방식.";
exit;
}

// 이부분이 다르죠..
// 전엔 이부분에서 첨부파일일경우 단순 링크만 시켜 놓았고..
// 여기서는 해당 부분을 그대로 출력합니다. 그렇게 되면 사용자 측에선
// 다운로드가 실행되는 것이죠..


switch($mime) {
case "PLAIN":
Header ( "Content-Type: text/plain");
echo str_replace("\n", "<br>", $val);
break;
case "HTML":
Header ( "Content-Type: text/html");
echo $val;
break;
case "OCTET-STREAM":
Header ( "Content-Type: octet-stream");
Header ( "Content-Disposition: attachment; filename=$file_name");
echo $val;
break;
default:
Header ( "Content-Type: octet-stream");
Header ( "Content-Disposition: attachment; filename=$file_name");
echo $val;
}
}

include ("mail_lib.php");

$box = $BOX;
$part_no = $PART_NO;
if($part_no == "") $part_no = 0;
if($box == "") $box = "INBOX";
$login = "userid";
$pass = "pwd";
$C_DOMAIN = "hagopa.co.kr";

$mailstream = imap_open("{" . $C_DOMAIN . ":143}" . $box, $login, $pass);

if ($mailstream == 0) {
echo "Error!
";
exit;
}

$struct = imap_fetchstructure($mailstream, $MSG_NO);
$part = $struct->parts[$part_no];
$param = $part->parameters[0];
$file_name = Decode($param->value); // 첨부파일일 경우 파일명
$mime = $part->subtype; // MIME 타입
$encode = $part->encoding; // encoding

printbody($mailstream, $MSG_NO, $part_no, $encode, $mime, $file_name);
imap_close($mailstream);
?>

, .

1. 메일 확인
2. 메일 조회
3. 메일 지우기
4. 메일 보내기

mail_detail.php

<?
// 필요한 서브 함수입니다.. 아래 메인의 소스를 보시고 이 함수 내용은 마지막에 보세요.
// 메일의 구조를 분석하는 함수


function checkstruct($mailstream, $MSG_NO) {
// 메일 구조 분석
$struct = imap_fetchstructure($mailstream, $MSG_NO);
// 메일의 구조를 객체로 리턴해 줍니다. 인자는 메일스트림과 해당 메일번호입니다.

$type = $struct->subtype;
/*
메일의 타입을 얻습니다. 크게 PLAIN, MIXED, ALTERNATIVE, RELATED 이렇게 있읍
니다.. ( 더 있는지도 모르죠... ^ ^)
PLAIN : 그냥 텍스트 메일이죠.. 이건 그냥 출력만 해주면 됩니다..
MIXED : 첨부파일이 있는 메일이란 건데... 이게 가장 복잡하죠.. 아래 switch문에
switch 문에서 설명하죠.
ALTERNATIVE : HTML 형식으로 메일을 보내면 이게 됩니다.
RELATED : HTML 형식으로 보낼때 보면 메일안에 이미지를 삽입해서 보낼 수 있습니다.
그 경우에 해당됩니다.

아래에서 자세히 보죠..
*/


switch($type) {
case "PLAIN": // 일반텍스트 메일
echo str_replace("\n", "<br>",
imap_fetchbody($mailstream, $MSG_NO, "1"));
// 그냥 본문을 얻어서 출력해 주면 됩니다.
// 본문을 얻는 방법은 위처럼 imap_fetchbody 함수를 사용하는데.. 여기서 세번째
// 인자가 "1" 이렇게 되어 있죠. 이것은 몌일의 body가 boundary라는 것으로 구분
// 되어 여러개가 올 수 있는데 그 중 첫번째 것이란 겁니다.. 당연 텍스트 메일은
// body가 하나밖에 없기에 그냥 무조건 위처럼 하면 됩니다.
break;
case "MIXED": // 첨부파일 있는 메일
/*
이게 좀 복잡하죠. 먼저 위에서 말했듯 첨부파일이 있는 것은 body가 여러개입니다.
즉 첨부파일이 두개인 text 메일일 경우 body는 세개로 나뉘죠..
이 세개의 body를 각각 표현하는 것이 되겠습니다.
*/
for($i=0;$i<count($struct->parts);$i++) {
// parts라는 속성에는 boundary로 구분된 body의 개체들이 들어 가게 됩니다.
// 이것의 갯수를 알아서 루프를 돌리는 거죠.


$part = $struct->parts[$i];
$param = $part->parameters[0];
$file_name = Decode($param->value);
// 첨부파일일 경우 파일명 Decode 함수는 어제 말한 제가 만든 거죠...
$mime = $part->subtype; // MIME 타입 혹은 메일의 종류가 리턴됩니다.
$encode = $part->encoding; // encoding

/*
아래 부분을 보면 $mime 이란 변수에 ALTERNATIVE 라는 것이 올수 있게 되어
있습니다.. 즉 OUTLOOK에서 HTML 형식으로 첨부파일을 보내면 대략
-메세지
-첨부파일1
-첨부파일2
-첨부파일3
이렇게 나뉘고 다시 메세지는
---PLAN
---HTML
이렇게 나뉘게 됩니다.. 이경우 메세지에 해당하는 부분이 ALTERNATIVE인 거죠..
*/
if($mime == "ALTERNATIVE") {
$val = imap_fetchbody($mailstream, $MSG_NO, (string)($numpart+1));
// 해당 part의 번호로 body에서 그 부분만 빼옵니다. 그리곤 이것을
// 화면에 출력하죠.. 아래 함수로.. 이것은 제가 만든 건데.. 나중에 설명하죠.
printOutLook($val);
} else {
printbody($mailstream, $MSG_NO, $i, $encode, $mime, $file_name);
// 첨부파일일 경우 printbody함수를 호출합니다.. 이건 바로 밑에 있는 함수인
// 데 거기서 설명하죠..
}
}
break;
case "ALTERNATIVE": // outlook html
for($i=0;$i<count($struct->parts);$i++) {
$part = $struct->parts[$i];
$param = $part->parameters[0];
$file_name = Decode($param->value); // 첨부파일일 경우 파일명
$mime = $part->subtype;
$encode = $part->encoding;

if($mime == "HTML") {
printbody($mailstream, $MSG_NO, $i, $encode, $mime, $file_name);
}
}
break;
case "RELATED": // outlook 본문에 이미지 삽입
for($i=0;$i<count($struct->parts);$i++) {
$part = $struct->parts[$i];
$param = $part->parameters[0];
$file_name = Decode($param->value); // 첨부파일일 경우 파일명
$mime = $part->subtype; // MIME 타입
$encode = $part->encoding; // encoding
if($mime == "ALTERNATIVE") {
$val = imap_fetchbody($mailstream, $MSG_NO, (string)($numpart+1));
printOutLook($val);
} else {
printbody($mailstream, $MSG_NO, $i, $encode, $mime, $file_name);
}
}
break;
}
}

// 메일 내용을 출력하는 함수
function printbody($mailstream, $MSG_NO, $numpart, $encode, $mime, $file_name) {
$val = imap_fetchbody($mailstream, $MSG_NO, (string)($numpart+1));
// 먼저 해당 part의 본문을 받아 옵니다.
// 그리고 인자값으로 넘어온 $encode 에 의해 먼저 본문을 decoding 해줍니다.

switch($encode) {
case 0: // 7bit
case 1: // 8bit
$val = imap_base64(imap_binary(imap_qprint(imap_8bit($val))));
break;
case 2: // binary
$val = imap_base64(imap_binary($val));
break;
case 3: // base64
$val = imap_base64($val);
break;
case 4: // quoted-print
$val = imap_base64(imap_binary(imap_qprint($val)));
break;
case 5: // other
echo "알수없는 Encoding 방식.";
exit;
}

// mime type 에 따라 출력합니다.
switch($mime) {
case "PLAIN":
echo str_replace("\n", "<br>", $val);
break;
case "HTML":
echo $val;
break;
default:
// 첨부파일인 경우이므로 다운로드 할 수 있게 링크를 걸어 줍니다.
echo "<br>첨부: <a href="mail_down.php?
MSG_NO=" . $MSG_NO . "&PART_NO=
" . $numpart . "" >" . $file_name . "</a>";
}
}
// ----------------------
// 메인 시작
// include 선언
// ----------------------
include ("mail_lib.php"); // 라이브러리 파일엔 지난번 강좌에 있던 Decode라는 함수가 있죠.
?>
<html>
<body>
<?
$box = $BOX; // 메일 박스명
if($box == "") $box = "INBOX";
switch($box) {
case "INBOX":
$box_name="받은 편지함";
break;
case "sent":
$box_name="보낸 편지함";
break;
}
?>
<body bgcolor="#FFFFFF" leftmargin=5 topmargin=20 marginwidth=5 marginheight=20>
<table width="610" border=0 bgcolor=#527900 cellpadding=4 cellspacing=0>
<tr>
<td align=center width="25" bgcolor="#334600">
<font face="Wingdings" size="4" color="#FFCC33">.</font></td>
<td width=95%>
<font size="3" color="#FFFFFF"><b>편지읽기</b></font>
</td>
</tr>
</table>
<table width=610 border=0 cellpadding=4 cellspacing=0 bgcolor=#D8D8D8>
<tr>
<td class="tk1" width=40%></td>
<td align="right" class="tk1" width=60%>
<a href="mail_cmd.php?CMD=del&NO[]=<?echo $MSG_NO;?>">삭제</a>
&nbsp;&nbsp;&nbsp;&nbsp;
[<a href="mail_list.php?BOX=<?echo $box;?>">목록</a>]
</td>
</tr>
</table>
<?
$login = "userid";
$pass = "pwd";
$C_DOMAIN = "hagopa.co.kr";

$mailstream = imap_open("{" . $C_DOMAIN . ":143}" . $box, $login, $pass);

if ($mailstream == 0) {
echo "Error!
";
exit;
}

// 메일 헤더 분석
$head = imap_header($mailstream,$MSG_NO);
$head->Unseen = "U";

$date = date("Y년 m월 d일 H시 i분", $head->udate);
$subject = $head->Subject;
$subject = Decode($subject);
$from_obj = $head->from[0];
$from_name = $from_obj->personal;
$from_addr = substr($from_obj->mailbox . "@" . strtolower($from_obj->host), 0, 30);
if($from_name == "") $from_name = $from_addr;
$from_name = Decode($from_name);

// 여기까지는 지난번 강좌에서 한 것과 동일하죠.. 설명 안하겠습니다.
?>
<table width=610 border=0 cellpadding=2 cellspacing=0 bordercolor=#E8E8E8>
<tr>
<td class="tk1" align="center" bgcolor="#EEEEEE" width="100">보낸날짜</td>
<td class="tk1" bgcolor="#F7F7F7"><?echo $date;?></td>
</tr>
<tr>
<td class="tk1" align="center" bgcolor="#EEEEEE">보낸이</td>
<td class="tk1" bgcolor="#F7F7F7"><?echo "<a href=mailto:$from_addr>$from_name</a>
";?></td>
</tr>
<tr>
<td class="tk1" align="center" bgcolor="#EEEEEE">제 &nbsp; 목</td>
<td class="tk1" bgcolor="#F7F7F7"><?echo $subject;?></td>
</tr>
</table>
<table width="610" border="0" cellpadding="4">
<tr>
<td class="tk1">
<?
checkstruct($mailstream, $MSG_NO);
imap_close($mailstream);

/*
위의 두개의 함수가 이번 강좌의 하이라이트죠... 하나 하나 설명합니다. 설명은 위에 해당 함수 선언된
곳을 보세요.
*/

?>
</td>
</tr>
</table>
<table width=610 border=0 cellpadding=4 cellspacing=0 bgcolor=#D8D8D8>
<tr>
<td class="tk1" width=40%></td>
<td align="right" class="tk1" width=60%>
<a href="mail_cmd.php?BOX=<?echo $box;?>&CMD=del&NO[]=<?echo $MSG_NO;?>">삭제</a>
&nbsp;&nbsp;&nbsp;&nbsp;
[<a href="mail_list.php?BOX=<?echo $box;?>">목록</a>]
</td>
</tr>
</table>
<br>
</body>
</html>
, .

1. 메일 확인
2. 메일 조회
3.메일 지우기
4. 메일 보내기

위의 순서에서 메일 확인 입니다.. 즉 사용자의 메일 박스를 뒤져서 메일 리스트를 화면에 출력해 주는 부분입니다.

mail_list.php

<html>
<body bgcolor="#FFFFFF" leftmargin=5 topmargin=20 marginwidth=5 marginheight=20>
<form name=frm method=post>
<?
$box = $BOX;
if($box == "") $box = "INBOX";

switch($box) {
case "INBOX":
$box_name="받은 편지함";
break;
case "sent":
$box_name="보낸 편지함";
break;
}

$login = "userid"; // 사용자 ID
$pass = "pwd"; // 사용자 비밀번호
$C_DOMAIN = "hagopa.co.kr"; // 서버 url

$mailstream = imap_open("{" . $C_DOMAIN . ":143}" . $box, $login, $pass);

if ($mailstream == 0) {
echo "Error!";
exit;
}
?>
<input type=hidden name=BOX value
="<?echo $box;?>">
<table width="610" border=0 bgcolor=#527900 cellpadding=4 cellspacing=0>
<tr>
<td align=center width="25" bgcolor="#334600">
<font face="Wingdings" size="4" color="#FFCC33">.</font></td> <td width="95%">
<font size="3" color="#FFFFFF"><b>편지읽기</b></font>

</td> </tr>
</table>
<table width="610" border="0" cellpadding="4" cellspacing="0">
<tr>
<td class="tk3">새편지 <?echo imap_num_recent($mailstream);?>개 /

<?echo imap_num_msg($mailstream);?>개 </td>
<td align=right class="tk3"></td>
</tr>
</table>

<table width="610" border="0" cellpadding="2" cellspacing="1">
<tr bgcolor="#E8E8E8">
<td class="tk1" align="right" width="8%">선택</td>
<td class="tk4" align="center" width=20%>받는이</td>
<td class="tk4" align="center" width=52%>제 목</td>
<td class="tk4" align="center" width=20%>날 짜</td>
</tr>
<?

/*

위에서 imap_num_recent 라는 함수와 imap_num_msg라는 함수는 새로운 편지와 총 메일의 수를 리턴해 주는 함수입니다.. 인자값으로는 메일스트림을 저정해 주면 되고요..

*/

$mailno = imap_sort($mailstream, SORTDATE, 1);

/*

연결된 메일박스에 있는 메일의 갯수와 함께.. 메일을 날짜 순으로 Desending 하는 부분입니다. 그리고 $mailno 에는 각 메일의 메일번호가 소트한 결과에 따라 차례로 배열로 저장됩니다. 이 번호를 가지고 루프를 돌리는 거죠... 아래 있습니다.

*/


if(count($mailno) == 0) {
?>
<tr bordercolor="#383838" height=35>
<td colspan=4 align=center class=tk1>편지함이 비어 있습니다.</td>
</tr>
<?
}

// 메일이 없을 경우 위와 같고요... 메일이 있는 경우 아래를 실행하겠죠.

for ($i=0;$i<count($mailno);$i++) { // 메일의 갯수만큼루프를 돕니다.
$no = $mailno[$i]; // 메일번호를 얻구요..
$head = imap_header($mailstream,$no);

// 얻어진 메일번호로 해당 메일의 헤더를 읽습니다.

$recent = $head->Recent; // 새메일 여부를 리턴해 줍니다.
$unseen = $head->Unseen; // 메일을 읽었는지 여부를 리턴해 주죠..
$msgno = trim($head->Msgno); // 메일번호

$date = date("Y/m/d H:i", $head->udate); // 메일의 날짜를 얻고
$subject = $head->Subject; // 제목을 얻습니다.

$subject = Decode($subject);

// 제목의 경우 OUT LOOK에서 보내면 인코딩을 자동으로 하기에 이를 디코딩해야 합니다.
//
그 부분을 처리해 주는 것으로 제가 만들었죠.. 그 내용은 맨 마지막에 있으니 참조하세요.


$from_obj = $head->from[0]; // 보낸 사람을 얻는 부분입니다. 그냥 아래처럼 사용하세요.
$from_name = $from_obj->personal;
$from_addr = substr($from_obj->mailbox . "@" . strtolower($from_obj->host), 0, 30);
if($from_name == "") $from_name = $from_addr;
$from_name = Decode($from_name);

if(strlen($from_name) > 13) $from_name = substr($from_name, 0, 10) . "...";

?>

<tr>
<td align=right><?echo $unseen;?> <input type=checkbox name=NO[] value=<?echo $msgno;?>></td>
<td>
<?echo "<a href=mailto:$from_addr>$from_name</a>";?></td>
<td><ahref="mail_detail.php? BOX=<?echo $box;?>&MSG_NO=<?echo $no;?>"><?echo$subject;?></a></td>
<td>
<?echo $date;?></td>
</tr>

<?
}

imap_close($mailstream);
?>
</table>
<SCRIPT LANGUAGE="JavaScript">
<!--
var selectVal = true;

function setSelected(button) {
for(var i=0;i<document.frm.length;i++) if(document.frm[i].name == 'NO[]') document.frm[i].checked = selectVal;
selectVal = selectVal ? false: true;
if (selectVal) {
button.value = '전체선택';

} else {
button.value = '전체해제';
}
return false;
}

function Delete(){
var count = 0;
for(var i=0;i<document.frm.length;i++){
if(document.frm[i].name == "NO[]" && document.frm[i].checked == true){ count++; }
}
if ( count != 0 ){
document.frm.action = "mail_cmd.php?CMD=del";
document.frm.submit();
} else { alert('삭제할 항목을 선택하세요!'); }
}
//-->
</SCRIPT>
<table width=610 border="0" bgcolor="#E8E8E8" cellspacing=0 cellpadding=3>
<tr>
<td class="tk3"><input type="button" name="Sub2" value="전체선택" onClick="setSelected(this);"></td>
<td align="right">
<input type=button name=HOWTO22 value="삭 제" class="tk1" onClick="Delete();">
</td> </tr>
</table>
<br>
</form>
</body>
</html>

위와 같네요.. 아까 위에서 나온 Decode라는 함수

OUTLOOK에서 보낸 메일만 테스트 했기에 다른 곳에서 보낼때 다르게 인코딩 되었다면

에러가 날 수도 있답니다.

<?
function Decode($val) {
if(substr($val,0,2) == "=?") {
//인코딩 여부 확인
$code = strpos($val, "?", 3);
$code = strpos($val, "?", $code+1);
$val = substr($val, $code+1, strlen($val)- $code-3);
return imap_base64($val);
} else { return $val; }
}
?>

위 함수를 본 파일 맨 위에 놓거나 다른 파일에 저장해서 include 해서 사용하면 됩니다. mail_lib.php 라고 만들어서 거기에 놓았죠
, .