php smtp email direct to mail box delivery

For sending status mails, with varying from addresses, for several of our projects at Saturn, we were using the phpmailer which uses our smtp server with authentication. Well our smtp host had a limitation of 250 emails per day. When our requirements grew out of this limit, mails started to pile up. Sure I could install exim4 or sendmail on my boxes, and that is what I did for immediate resolution. But here comes a new requirement, that the mails sent should be marked as such, and those which failed should be marked with the exact response of the receiving end mailserver.

At this point I thought about an SMTP direct to mail box Delivery system. My favorite language being PHP, and primary library being Google, I tried all possible ways, according to me, and they were not the right ones as I came to know later. All these did not get me in the right direction. And finally thought about writing one. Here too, being lazy, wanted to have the code from some ones work to ignite me. Okay I found the phpbb’s smtp.php referred on the net, and the function smtpmail from the same was the right choice.

Starting these as a base, I worked my way in, and wrote the smtpSend class. Well we needed to find the mail exchangers for the receipient. PHP’s built in function getmxrr came to the help. This was abstracted to a protected function getMxHosts.



    
protected function _getMxHosts($to){
        
$response = array('mx' => array(), 'weight' => array());
        list(
$user$host) = explode('@'$to);
        if(
getmxrr $host$response['mx'], $response['weight'] )){
            return 
$response;
        }
        return 
false;
    }
 

Used the server_parse function almost the same, with just some debugging sprinkled about, and changed the function name to _parse such that it could be used from the class.


    
protected function _parse($socket$response$line __LINE__$level 1
    { 
        while (@
substr($server_response31) != ' '
        {
            if (!(
$server_response fgets($socket256))) 
            { 
                
$this->_die("Couldn't get mail server response codes"$line__FILE__); 
            } 
            if(
$this->debug >= $level
                echo 
$server_response;
        } 
 
        if (!(
substr($server_response03) == $response)) 
        { 
            
$this->_die("Ran into problems sending Mail. Response: $server_response"$line__FILE__); 
        }else{
            return 
substr($server_response4);
        } 
    }

In phpbb they already had a function message_die which was being called at several points, for which I wrote _die, and made corresponding changes where ever used. Then fputs was being used in plenty, and for vaying level of debugging, or showing off, this would also be better if there is an echo before sending to the socket. Hence fputs was also abstracted to _sockPut.


    
protected function _die($msg$line$file){
        
$this->error trim($msg). " @ $file:$line ";
    }
    
    protected function 
_sockPut(&$socket$msg$level 1){
        if(
$this->debug >= $level
            echo 
$msg;
        
fputs($socket$msg);
    }
 

The main flow was changed from the phpbb smtp.php function, since that was meant to be used with a local or remote smtp server with or without authentication. And it does not have much difference than using a locally available mail delivery agent. And our requirements were meager. The total function was changed, the header parsing was removed, mx hosts for the receipient was identified, and each was tried in a sequence to be connected till we got one or altogether we failed in sending the mail. The portion which uses our own smtp server was removed. The sanitation of the to field was removed, and assumption that to field will contain multiple address is also off. Sprinkled the debugging calls and changed the internal calls.

Without a sample implementation would this be complete ?


 
require("./class.smtpSend.php");
 
$subject "Test Mail by php-smtp-server";
$message 'I am testing my php direct to mailbox system, which
actually connects to the receipient mailbox and delivers
the mail. This is just the preliminary test phase.
 
- Jiju
https://www.jijutm.com
'
;
 
$headers 'From: "Jiju Thomas Mathew" <your@email.address>
Reply-To:  <your@email.address>
X-Generated-By: class.smtpSend.php'
;
 
$smtp = new smtpSend('your@email.address');
 
if(!
$smtp->send('receipient@his.mail.server'$subject$message$headers)){
    echo 
$smtp->getError();
}
 

The final combined class is put here for downloading. Download