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
행복해지고 싶다면, 잠시 동안만이라도 가슴에 손을 얹고 생각해 보라. 그러면 진정한 즐거움은, 발치에 돋아나는 잡초나 아침 햇살에 빛나는 꽃의 이술과 같이 우리 주변에 무수히 널려 있다는 것을 알 수 있을 것이다. 《하루 5분 생각이 인생을 결정한다 》 (이범준)