PHP & Others

메일발송 - smtp 클래스에서 auth 인증 추가

컨텐츠 정보

본문

 
글쓴이:치즈버거  smtp 클래스에서 auth 인증 추가 조회수:205


 http://www.phpschool.com/bbs2/inc_view.html?id=7487&code=tnt2
 http://ze.to/lib/class.Smtp.phps



mail() 함수의 어설픔으로 인해 하근호님의 팁 (링크#1) 을 잘 사용하고 있던 중 auth 인증을 필요로 하는 smtp 서버에서 사용해야할 필요가 생겼습니다.
관련 정보가 부족해서 여기저기 알아보다가 성공했습니다.
(사실 1년 가까이 된 일인데 이제야 올리네요)

하근호님의 smtp클래스 (링크#2) 중 95번째 라인 (if(!$rcpt_to = $this->get_email($email)) return false; 와 if(!$this->dialogue(250, "MAIL FROM:$mail_from")) return false; 사이) 에 다음내용을 삽입하시면 됩니다.

$id = "아이디@도메인";
$pwd = "비밀번호";
if(!$this->dialogue(250, "AUTH LOGIN\\n")) return false;
if(!$this->dialogue(250, base64_encode($id)."\\n")) return false;
if(!$this->dialogue(250, base64_encode($pwd)."\\n")) return false;

$id 는 서버에 따라 아이디만 쓰는 경우도 있고 아이디@도메인 까지 쓰는 경우도 있죠.
알맞게 넣어주시면 됩니다.

// 하근호님께 허락 없이 링크 참조해서 죄송합니다~

 
-----------------------------------
<?php

/***************************************/
/* 파일명 : class.Smtp.php
/* 제작일 : 2002-08-30
/* 제작자 : 하근호(hopegiver@korea.com)
/***************************************/

class Smtp {

    var $host;
    var $fp;
    var $lastmsg;
    var $parts;
    var $debug;
    var $charset;
    var $ctype;
    var $BCC;
    var $CC;

    function Smtp($host = "localhost") {
        $this->host = $host;
        $this->parts = array();
        $$this->debug = 0;
        $this->charset = "euc-kr";
        $this->ctype = "text/html";
    }

    // 디버그 모드 : 1
    function debug($n=1) {
        $this->debug = $n;
    }

    // smtp 통신을 한다.
    function dialogue($code, $cmd) {

        fputs($this->fp, $cmd."\\r\\n");
        $line = fgets($this->fp, 1024);
        ereg("^([0-9]+).(.*)$", $line, &$data);
        $this->lastmsg = $data[0];

        if($this->debug) {
            echo htmlspecialchars($cmd)."<br>".$this->lastmsg."<br>";
            flush();
        }

        if($data[1] != $code) return false;
        return true;

    }

    //  smptp 서버에 접속을 한다.
    function connect($host='') {

        if($this->debug) {
            echo "SMTP($host) Connecting...<br>";
            flush();
        }

        if(!$host) $host = $this->host;
        if(!$this->fp = fsockopen($host, 25, $errno, $errstr, 10)) {
            $this->lastmsg = "SMTP($host) 서버접속에 실패했습니다.[$errno:$errstr]";
            return false;
        }

        $line = fgets($this->fp, 1024);
        ereg("^([0-9]+).(.*)$", $line, &$data);
        $this->lastmsg = $data[0];
        if($data[1] != "220") return false;

        if($this->debug) {
            echo $this->lastmsg."<br>";
            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) {

        if(!$mail_from = $this->get_email($from)) return false;
        if(!$rcpt_to = $this->get_email($email)) 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:<postmaster>");
            $this->dialogue(354, "DATA");   
            $this->dialogue(250, ".");
            return false;
        }
        //$this->dialogue(250, "RCPT TO:<hopegiver@whois.co.kr>");
        $this->dialogue(354, "DATA");

        $mime = "Message-ID: <".$this->get_message_id().">\\r\\n";
        $mime .= "From: $from\\r\\n";
        $mime .= "To: $email\\r\\n";

        /*
        if($this->CC) $mime .= "Cc: ".$this->CC."\\r\\n";
        if($this->BCC) $mime .= "Bcc: ".$this->BCC."\\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 = count($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(!ereg("([\\._0-9a-zA-Z-]+)@([0-9a-zA-Z-]+\\.[a-zA-Z\\.]+)", $email, $reg)) return false;
        getmxrr($reg[2], $host);
        if(!$host) $host[0] = $reg[2];
        return $host;

    }

    // 이메일의 형식이 맞는지 체크한다.
    function get_email($email) {
        if(!ereg("([\\._0-9a-zA-Z-]+)@([0-9a-zA-Z-]+\\.[a-zA-Z\\.]+)", $email, $reg)) return false;
        return "<".$reg[0].">";
    }

    //대용량 발송을 위한 함수.
    function send($to, $from, $subject, $body) {
        $data = $this->build_data($subject, $body);
        return $this->smtp_send($to, $from, $data);
    }

    // 메일을 전송한다.
    function sendmail($to, $from, $subject, $body, $type=1) {
       
        if($type == 0) $this->ctype = "text/plain";

        if(!is_array($to)) $to = split("[,;]",$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);
                        $this->close();
                    }
                }
            }
        } else {
            $this->connect($this->host);
            foreach($to as $email) $this->smtp_send($email, $from, $data);
            $this->close();
        }
    }

}

/*
$mail = new Smtp;
$mail->debug();
$mail->sendmail("photon0@hanmail.net", "hopegiver@whois.co.kr", "이 메일은 정상입니다.", "정상적인 메일이니 삭제하지 마십시오.");

OR

$mail->connect();
$mail->send();
$mail->close();

*/

?>

사용방법은 간단합니다.

$mail = new Smtp("self");  //자체발송일 경우, 서버를 지정할수도 있음.
$mail->debug();  //디버깅할때
$mail->attach("파일버퍼", "파일이름", "파일타입");
$mail->send("받을 사람메일주소", "보내는사람 메일주소", "제목", "내용");

 

관련자료

댓글 0
등록된 댓글이 없습니다.
Today's proverb
“무릇 물이란 지세를 따라 흐르되 작은 틈도 놓치지 않고 적시니 지혜를 갖춘 자와 같고, 움직이면서 아래로 흘러가니 예를 갖춘 자와 같으며, 어떤 깊은 곳도 머뭇거리지 않고 들어가니 용기를 가진 자와 같고 장애물이 막혀서 갇히면 고요히 맑아지니 천명을 아는 자와 같으며, 험한 곳을 거쳐 멀리 흐르지만 끝내 남을 허물어뜨리는 법이 없으니 덕을 가진 자와 같다. 천지는 이것으로 이루어지고, 만물은 이것으로 살아가며, 나라는 이것으로 안녕을 얻고, 만사는 이것으로 평안해지며, 만물은 이것으로 바르게 되는 것이다. 이것이 지혜로운 자가 물을 좋아하는 이유이다.” (한영, <<한시외전>>)