PHP Code: 
<?php
class smtp

    
{
    const 
NL "\r\n";
    const 
READY '220';
    const 
OK '250';
    const 
TEXT64 '334';
    const 
AUTHOK '235';
    const 
DATAOK '354';
    const 
BYE '221';
    const 
MAILER 'PHP smtp class';
    protected 
$_smtp null;
    protected 
$_server = array(
        
'host' => null,
        
'port' => 25,
        
'timeout' => 3,
    );
    protected 
$_user;
    protected 
$_pass;
    protected 
$_charset 'UTF-8';
    protected 
$_from;
    protected 
$_mailFrom null;
    protected 
$_replyTo = array();
    protected 
$_to = array();
    protected 
$_cc = array();
    protected 
$_bcc = array();
    protected 
$_priority;
    protected 
$_headers = array();
    protected 
$_subject;
    protected 
$_text = array(
        
'body' => '',
        
'Content-Type' => 'text/plain',
        
'charset' => 'UTF-8'
    
);
    protected 
$_attachments = array();
    protected 
$_raw = array();
    protected 
$_log '';
    protected
    function 
_encode($W)
        {
        if (
$this->_charset)
            {
            return 
'=?' $this->_charset '?B?' base64_encode($W) . '?=';
            }
          else
            {
            return 
$W;
            }
        }

    protected
    function 
_recipients($N$O$K)
        {
        if (
in_array($K, array(
            
'_to',
            
'_cc',
            
'_bcc'
        
)))
            {
            if (
$O)
                {
                if (
$N$this->
                    {
                    
$K}[$O] = $N;
                      else
                        {
                        if (isset(
$this->
                            {
                            
$K}[$O])) unset($this->
                                {
                                
$K}[$O]);
                                }
                            }
                          else
                            {
                            if (
$N$this->
                                {
                                
$K}[] = $N;
                                }
                            }
                          else throw new 
Exception('Wrong recipient');
                        }

                    protected
                    function 
_dialog($Q$d)
                        {
                        
$this->_log.= $Q PHP_EOL;
                        
fwrite($this->_smtp$Q self::NL);
                        
$F fgets($this->_smtp);
                        
$this->_log.= $F PHP_EOL;
                        if (
substr($F03) != $d) throw new Exception('Message "' $Q '" NOT accepted! Here is the dialog dump:' PHP_EOL $this->_log);
                        return 
$F;
                        }

                    function 
_connect()
                        {
                        if (empty(
$this->_smtp))
                            {
                            if (
$this->_smtp fsockopen($this->_server['host'], $this->_server['port'], $e$a$this->_server['timeout']))
                                {
                                if (
substr($F fgets($this->_smtp) , 03) != self::READY) throw new Exception('Server NOT ready! The server responded with this message:' PHP_EOL $F);
                                
$this->_log $F PHP_EOL;
                                
$f explode('@'$this->_from['address']);
                                
$this->_dialog('HELO ' $f[1], self::OK);
                                if (
$this->_user && $this->_pass)
                                    {
                                    
$this->_dialog('auth login'self::TEXT64);
                                    
$this->_dialog($this->_userself::TEXT64);
                                    
$this->_dialog($this->_passself::AUTHOK);
                                    }
                                }
                              else
                                {
                                
$A 'Unable to connect to ' $this->_server['host'] . ' on port ' $this->_server['port'] . ' within ' $this->_server['timeout'] . ' seconds' PHP_EOL;
                                if (!empty(
$a)) $A.= 'The remote server responded:' PHP_EOL $a '(' $e ')';
                                throw new 
Exception($A);
                                }
                            }
                        }

                    function 
__construct($X$Y 25$b 3)
                        {
                        if (empty(
$X)) throw new Exception('Undefined SMTP server');
                        
$this->_server['host'] = (string)$X;
                        if (
$Y$this->_server['port'] = (integer)$Y;
                        if (
$b$this->_server['timeout'] = (integer)$b;
                        }

                    function 
__destruct()
                        {
                        
$this->_dialog('QUIT'self::BYE);
                        if (
$this->_smtpfclose($this->_smtp);
                        }

                    function 
auth($n$g)
                        {
                        
$this->_user base64_encode($n);
                        
$this->_pass base64_encode($g);
                        }

                    function 
charset($E)
                        {
                        
$this->_charset = (string)$E;
                        }

                    function 
from($J null$B '')
                        {
                        if (
null !== $J)
                            {
                            
$this->_from['address'] = (string)$J;
                            
$this->_from['name'] = (string)$B;
                            }

                        return 
$this->_from;
                        }

                    function 
mailFrom($V null)
                        {
                        if (
null !== $V$this->_mailFrom = (string)$V;
                        return 
$this->_mailFrom;
                        }

                    function 
replyTo($Z null$B null)
                        {
                        if (
null !== $Z)
                            {
                            
$this->_replyTo['address'] = (string)$Z;
                            
$this->_replyTo['name'] = (string)$B;
                            }

                        return 
$this->_replyTo;
                        }

                    function 
to($m null$l '')
                        {
                        
$this->_recipients($m$l'_to');
                        return 
$this->_to;
                        }

                    function 
cc($i null$h '')
                        {
                        
$this->_recipients($i$h'_cc');
                        return 
$this->_cc;
                        }

                    function 
bcc($j null$k '')
                        {
                        
$this->_recipients($j$k'_bcc');
                        return 
$this->_bcc;
                        }

                    function 
priority($G null)
                        {
                        if (
$G)
                            {
                            
$G = (integer)$G;
                            if ((
$G 0) && ($G 6)) $this->_priority $G;
                              else throw new 
Exception('Priority are integer from 1 (low) to 5 (high)');
                            }

                        return 
$this->_priority;
                        }

                    function 
header($B null$P null)
                        {
                        if (
$B$this->_headers[(string)$B] = (string)$P;
                        return 
$this->_headers;
                        }

                    function 
subject($U null)
                        {
                        if (
null !== $U$this->_subject = (string)$U;
                        return 
$this->_subject;
                        }

                    function 
text($T null$I 'text/plain'$E 'utf-8')
                        {
                        if (
null !== $T)
                            {
                            
$this->_text = array(
                                
'body' => str_replace("\n"self::NL, (string)$T) ,
                                
'Content-Type' => $I,
                                
'charset' => $E
                            
);
                            }

                        return 
$this->_text;
                        }

                    function 
attachment($L null$B ''$I 'application/octet-stream'$E 'utf-8')
                        {
                        if (
is_readable($L))
                            {
                            
$R = array(
                                
'path' => (string)$L,
                                
'Content-Type' => (string)$I,
                                
'charset' => (string)$E
                            
);
                            
$B || ($B pathinfo($LPATHINFO_BASENAME));
                            
$this->_attachments[$B] = $R;
                            }
                        elseif (!empty(
$L)) throw new Exception('File ' $L ' not found or not readable');
                        return 
$this->_attachments;
                        }

                    function 
raw($S null$B ''$I 'text/plain'$E 'utf-8')
                        {
                        if (
$S)
                            {
                            
$R = array(
                                
'content' => (string)$S,
                                
'Content-Type' => (string)$I,
                                
'charset' => (string)$E
                            
);
                            if (empty(
$B)) $B time() . '-' mt_rand();
                            
$this->_raw[$B] = $R;
                            }

                        return 
$this->_raw;
                        }

                    function 
clear()
                        {
                        
$this->_to = array();
                        
$this->_cc = array();
                        
$this->_bcc = array();
                        
$this->_headers = array();
                        
$this->_attachments = array();
                        
$this->_raw = array();
                        }

                    function 
send()
                        {
                        if (empty(
$this->_from)) throw new Exception('Sender undefined');
                        if (empty(
$this->_to) && empty($this->_cc) && empty($this->_bcc)) throw new Exception('No recipients');
                        if (empty(
$this->_subject)) throw new Exception('No subject');
                        if (empty(
$this->_text)) throw new Exception('No message text');
                        
$this->_connect();
                        if (
$this->_mailFrom$J $this->_mailFrom;
                          else 
$J $this->_from['address'];
                        
$this->_dialog('MAIL FROM:<' $J '>'self::OK);
                        foreach(
$this->_to as $C$this->_dialog('RCPT TO:<' $C '>'self::OK);
                        foreach(
$this->_cc as $C$this->_dialog('RCPT TO:<' $C '>'self::OK);
                        foreach(
$this->_bcc as $C$this->_dialog('RCPT TO:<' $C '>'self::OK);
                        
$this->_dialog('DATA'self::DATAOK);
                        
$A '';
                        if (empty(
$this->_from['name'])) $A.= 'From: <' $this->_from['address'] . '>' self::NL;
                          else 
$A.= 'From: "' $this->_encode($this->_from['name']) . '"<' $this->_from['address'] . '>' self::NL;
                        if (!empty(
$this->_replyTo))
                            {
                            if (empty(
$this->_replyTo['name'])) $A.= 'Reply-To: <' $this->_replyTo['address'] . '>' self::NL;
                              else 
$A.= 'Reply-To: "' $this->_encode($this->_replyTo['name']) . '"<' $this->_replyTo['address'] . '>' self::NL;
                            }

                        foreach(
$this->_to as $B => $C)
                            {
                            if (
is_integer($B)) $A.= 'To: <' $C '>' self::NL;
                              else 
$A.= 'To: "' $this->_encode($B) . '"<' $C '>' self::NL;
                            }

                        foreach(
$this->_cc as $B => $C)
                            {
                            if (
is_integer($B)) $A.= 'Cc: <' $C '>' self::NL;
                              else 
$A.= 'Cc: "' $this->_encode($B) . '"<' $C '>' self::NL;
                            }

                        foreach(
$this->_bcc as $B => $C)
                            {
                            if (
is_integer($B)) $A.= 'Bcc: <' $C '>' self::NL;
                              else 
$A.= 'Bcc: "' $this->_encode($B) . '"<' $C '>' self::NL;
                            }

                        if (
$this->_priority$A.= 'X-Priority: ' $this->_priority self::NL;
                        
$A.= 'X-mailer: ' self::MAILER self::NL;
                        
$A.= 'X-mailer-author: ' self::MAILER_AUTHOR self::NL;
                        foreach(
$this->_headers as $B => $P$A.= $B ': ' $P self::NL;
                        
$A.= 'Date: ' date('r') . self::NL;
                        
$A.= 'Subject: ' $this->_encode($this->_subject) . self::NL;
                        if (
$this->_attachments || $this->_raw)
                            {
                            
$M hash('sha256'time());
                            
$A.= 'MIME-Version: 1.0' self::NL;
                            
$A.= 'Content-Type: multipart/mixed; boundary=' $M self::NL;
                            
$A.= self::NL;
                            
$A.= 'This is a message with multiple parts in MIME format.' self::NL;
                            
$A.= '--' $M self::NL;
                            
$A.= 'Content-Type: ' $this->_text['Content-Type'] . '; charset=' $this->_text['charset'] . self::NL;
                            
$A.= self::NL;
                            
$A.= $this->_text['body'] . self::NL;
                            foreach(
$this->_attachments as $B => $D)
                                {
                                
$A.= '--' $M self::NL;
                                
$A.= 'Content-Disposition: attachment; filename=' $B '; modification-date="' date('r'filemtime($D['path'])) . '"' self::NL;
                                if (
substr($D['Content-Type'], 05) == 'text/')
                                    {
                                    
$A.= 'Content-Type: ' $D['Content-Type'] . '; charset=' $D['charset'] . self::NL;
                                    
$A.= self::NL;
                                    
$A.= file_get_contents($D['path']) . self::NL;
                                    }
                                  else
                                    {
                                    
$A.= 'Content-Type: ' $D['Content-Type'] . self::NL;
                                    
$A.= 'Content-Transfer-Encoding: base64' self::NL;
                                    
$A.= self::NL;
                                    
$A.= base64_encode(file_get_contents($D['path'])) . self::NL;
                                    }
                                }

                            foreach(
$this->_raw as $B => $H)
                                {
                                
$A.= '--' $M self::NL;
                                
$A.= 'Content-Disposition: attachment; filename=' $B '; modification-date="' date('r') . '"' self::NL;
                                if (
substr($H['Content-Type'], 05) == 'text/')
                                    {
                                    
$A.= 'Content-Type: ' $H['Content-Type'] . '; charset=' $H['charset'] . self::NL;
                                    
$A.= self::NL;
                                    
$A.= $H['content'] . self::NL;
                                    }
                                  else
                                    {
                                    
$A.= 'Content-Type: ' $H['Content-Type'] . self::NL;
                                    
$A.= 'Content-Transfer-Encoding: base64' self::NL;
                                    
$A.= self::NL;
                                    
$A.= base64_encode($H['content']) . self::NL;
                                    }
                                }

                            
$A.= '--' $M '--' self::NL;
                            }
                          else
                            {
                            
$A.= 'Content-Type: ' $this->_text['Content-Type'] . '; charset=' $this->_text['charset'] . self::NL;
                            
$A.= self::NL $this->_text['body'] . self::NL;
                            }

                        
$A.= '.';
                        
$c $this->_dialog($Aself::OK);
                        return 
substr($c4);
                        }

                    function 
dump()
                        {
                        return 
$this->_log;
                        }
                    }
Basic usage



$smtp = new Smtp('smtp_server');
$smtp->from('user@domain');
$smtp->to('dest@anotherdomain');
$smtp->subject('subject');
$smtp->text('message');
$smtp->send();


Advanced usage



$smtp = new Smtp('smtp_server', 25, 3);
$smtp->from('user@domain', 'My name');
$smtp->mailFrom('my_account@domain');
$smtp->replyTo('anotheraddress@anotherdomain');
$smtp->priority(4);
$smtp->header('MyCustomHeader', 'The value of my custom header');
$smtp->to('addr1@domain', 'My friend');
$smtp->to('addr2@anotherdomain', 'Another friend');
$smtp->cc('addr3@domain', 'My mama');
$smtp->cc('addr4@domain', 'My papa');
$smtp->bcc('addr5@domain', 'My cat');
$smtp->subject('Birthday invitation');
$smtp->text('Want you come to my party?', 'text/plain', 'utf-8');
$smtp->attachment('/path/to/my/picture', 'me.jpg', 'image/jpeg');
$smtp->attachment('/path/to/businesscard', 'me.html', 'text/html', 'utf-8');
$smtp->raw('Here are directions to my home', 'directions.txt', 'text/plain', 'iso-8859-1');
$imagedata = imagecreatefrompng($imagefile);
// Add watermarks
ob_start();
imagepng($imagedata);
$stringdata = ob_get_contents(); // read from buffer
ob_end_clean();
$smtp->raw($stringdata, 'Flyer.jpg', 'image/jpeg');
$smtp->charset('UTF-8'); // For subject, names, etc.
$smtp->send();

$smtp->clear(); // Clear recipients and attachments
$smtp->from('anewsender@anewdomain');
$smtp->mailFrom('setanewmailfrom@anewdomain');
$smtp->replyTo('');
$smtp->to('anewdest@anothernewdomain');
$smtp->subject('newsubject');
$smtp->text('newmessage');
$smtp->send();

echo $smtp->dump(); // Dump the full logging


FEATURES


  • multiple recipients
  • To, Cc, Bcc recipients
  • named recipients
  • separate 'MAIL FROM' management
  • Reply-To management
  • priority management
  • custom headers
  • Content-Type equipped text (e.g. text/html)
  • attachments from file
  • attachments from string
  • binary attachments (from file or string)
  • Content-Type full management, per part
  • multiple dispatches in one connection
Kepler Reviewed by Kepler on . PHP SMTP Client <?php class smtp { const NL = "\r\n"; const READY = '220'; const OK = '250'; const TEXT64 = '334'; const AUTHOK = '235'; const DATAOK = '354'; Rating: 5