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
범은 가죽을 아끼고, 군자는 입을 아낀다.