TUTORIAL: Sending Email VIA SMTP

  • Bogey
  • Genius
  • Genius
  • Bogey
  • Posts: 8388
  • Loc: USA

Post 3+ Months Ago

1.0 Introduction


There are many instances when you (as a web master/site owner) want to send your users an email, or allow the users send other users an email. Obviously you would want to code some permissions into that and enable the users to disable other users to send emails to them, otherwise it could get quite ugly.

The main purpose of this tutorial is to break down existing code into little bits and explain what each line does, so when you are using the code, you would be able to use it and actually understand what it's doing.

1.1 Copyright Notice


This class isn't my original, so I don't own this class. I got it as a simple PHP page and converted it into a class and edited it a bit... but I didn't create it from scratch.

2.0 SMTP Servers


Most hosts provide an SMTP server (and POP server) that is available for you to use for this very purpose. In most cases, the link to the SMTP server would look something like: smtp.myhost.com.

In most cases a normal port to SMTP would be 25 while a secure port to SMTP would be 465. If it's not those ports then the host should tell you which ports are the SMTP ports. (They will tell you the ports even if they are those ports).

2.1 SMTP Alternatives


If, for any reason your host does not provide you with an SMTP server for you to use, there are a few alternatives out there that you can use. The first one that comes to mind is gmail.

Gmail allows you to use their SMTP server to send email messages for free and without any hassle. By that, I mean you don't have to go to gmail and enable SMTP or anything like that... it's always there so all you need to do is fill out the information into the script and it would work. Below are the information that enables you to use their SMTP server:

SMTP server: smtp.gmail.com
Port: 587
Username: {your gmail email (e.i: myname@gmail.com)}
Password: {your password to your email}

There are others besides gmail that provide you with an SMTP server. One, for example, is SMTP.com, but as you can see, that is a bit more expensive alternative that gmail.com is.

3.0 The Class Initiation


I've wanted a simple class to enable me to have user's send to users, me send to users and then user's sending to me... I found a function that limited the email service to me sending to users and that's it. Obviously there must be something that I had to do, to increase the capabilities of that function.

The way I wanted to use that function is:

PHP Code: [ Select ]
new mail($to, $subject, $message)


A one-liner, in my opinion, is a really big plus when it comes to this... a one liner that returns true if the message was sent or false if the message failed to be sent.

This enables me to wrap that one liner with an if() statement and return the user with the status of their message.

3.1 The Variable Declaration


There are a few variables declared in the class to make this class usable:
PHP Code: [ Select ]
class mail {
    private $smtpServer = 'smtp.gmail.com';
    private $port = '587';
    private $timeout = 30;
    private $username = 'myname@gmail.com';
    private $password = 'mypassword';
    private $username_email = 'myreceivingemail@gmail.com';
    private $newline = "\r\n";
    private $localdomain = 'http://www.mysite.com';
    private $charset = 'windows-1251';
    private $contentTransferEncoding = false;
 
    // Do not change anything below
    private $smtpConnect = false;
    private $to = false;
    private $subject = false;
    private $message = false;
    private $headers = false;
    private $logArray = array(); // Array response message for debug
    private $Error = '';
    private $from = false;
}
  1. class mail {
  2.     private $smtpServer = 'smtp.gmail.com';
  3.     private $port = '587';
  4.     private $timeout = 30;
  5.     private $username = 'myname@gmail.com';
  6.     private $password = 'mypassword';
  7.     private $username_email = 'myreceivingemail@gmail.com';
  8.     private $newline = "\r\n";
  9.     private $localdomain = 'http://www.mysite.com';
  10.     private $charset = 'windows-1251';
  11.     private $contentTransferEncoding = false;
  12.  
  13.     // Do not change anything below
  14.     private $smtpConnect = false;
  15.     private $to = false;
  16.     private $subject = false;
  17.     private $message = false;
  18.     private $headers = false;
  19.     private $logArray = array(); // Array response message for debug
  20.     private $Error = '';
  21.     private $from = false;
  22. }

Here are those variables broken down.

  • smtpServer
    • The SMTP server you would be connecting to and using to send messages
  • port
    • The port that you would be using to connect to the SMTP server
  • timeout
    • length of time (in seconds) that the script would try to connect before deciding it won't connect
  • username
  • password
    • The password to that email to enable the use of the SMTP server
  • username_email
    • This is the email that will receive the messages from the user... doesn't have to be from Gmail.
  • newline
    • This is how the script will make newlines in the error and debug messages.
  • localdomain
    • This is a link to your site.
  • charset
    • The character set (encoding I believe) that is used in that message
  • contentTransferEncoding
    • If set to true, it would put in the header that the content is encoded (I believe... don't think it would actually encode the content
  • smtpConnect
    • This would be holding the SMTP link identifier on success and false on failure. Would be used to determine the status of the connection (obviously)
  • to
    • The Email address to whom the message is addressed to.
  • subject
    • This would be the subject of the email being sent.
  • message
    • The actual body of the message.
  • headers
    • This will hold the headers to the message in the class... it's declared here as a holder to be used later on. Not meant to be changes and set to different headers here in the declaration.
  • logArray
    • This array would hold every response (sent?) and received within the script for debug. It would be printed into the source (not the page) for debug purposes (it would be the first thing between the HTML comments tag <!-- debug -->
  • Error
    • This variable would hold the errors that it came across and upon failure, it would print the errors for everyone to see.
  • from
    • This variable is used in the constructor function to figure out who is sending. If to_admin (in constructor function) is set to true then the from variable would be set to the user's email address... if the variable to_admin is set to false, then the from variable would be set to the admin's email address.

3.2 The Constructor Function


The constructor function is what brings everything to one place and enables you to use the features of the class.
PHP Code: [ Select ]
function __construct($to, $subject, $message, $to_admin) {

The construct function declaration. Sets the dynamic variables that would be used throughout the entire class.
PHP Code: [ Select ]
    $this->to = (($to_admin === true) ? $this->username_email : $to );

This is the line that determines the recipient of the email message. If $to_admin is true then it's to admin, otherwise it's not to admin.
PHP Code: [ Select ]
    $this->from = (($to_admin === false) ? $to : $this->username_email );

This is the line that determines the sender of the email message. If $to_admin is set to true then it's not from the admin, otherwise it is. (This probably needs some editing to have it be correct when it's from user to user).
PHP Code: [ Select ]
    $this->subject = &$subject;

Well, this be the subject of the message.
PHP Code: [ Select ]
    $this->message = &$message;

And this here is the message of the message.
PHP Code: [ Select ]
    // Connect to server
    if(!$this->Connect2Server()) {
  1.     // Connect to server
  2.     if(!$this->Connect2Server()) {

Here is where we check the result of the connection attempt. Checking specifically for failure. If it's a success we don't need (shouldn't) echo anything.
PHP Code: [ Select ]
        // Display error message
        echo '<pre>'.trim($this->Error).'</pre>'.$this->newline.'<!-- '.$this->newline;
        print_r($this->logArray);
        echo $this->newline.'-->'.$this->newline;
        return false;
    }
  1.         // Display error message
  2.         echo '<pre>'.trim($this->Error).'</pre>'.$this->newline.'<!-- '.$this->newline;
  3.         print_r($this->logArray);
  4.         echo $this->newline.'-->'.$this->newline;
  5.         return false;
  6.     }

This is where we print the errors to the screen and the debug to the source code... we also return false to let you print a message to the user telling them that sending that message didn't work out.
PHP Code: [ Select ]
    return true;
}
  1.     return true;
  2. }

If the connection worked, and the if statement that checks for failure didn't trigger, then we return true to enable you to print a message to the user telling them that the message was sent successfully.

Below is the function in it's entirety.
PHP Code: [ Select ]
public function __construct($to, $subject, $message, $to_admin) {
    $this->to_admin = $to_admin;
    $this->to = (($this->to_admin === false) ? $this->username_email : $to );
    $this->from = (($this->to_admin === false) ? $to : $this->username_email );
    $this->subject = &$subject;
    $this->message = &$message;
 
    // Connect to server
    if(!$this->Connect2Server()) {
        // Display error message
        echo '<pre>'.trim($this->Error).'</pre>'.$this->newline.'<!-- '.$this->newline;
        print_r($this->logArray);
        echo $this->newline.'-->'.$this->newline;
        return false;
    }
    return true;
}
  1. public function __construct($to, $subject, $message, $to_admin) {
  2.     $this->to_admin = $to_admin;
  3.     $this->to = (($this->to_admin === false) ? $this->username_email : $to );
  4.     $this->from = (($this->to_admin === false) ? $to : $this->username_email );
  5.     $this->subject = &$subject;
  6.     $this->message = &$message;
  7.  
  8.     // Connect to server
  9.     if(!$this->Connect2Server()) {
  10.         // Display error message
  11.         echo '<pre>'.trim($this->Error).'</pre>'.$this->newline.'<!-- '.$this->newline;
  12.         print_r($this->logArray);
  13.         echo $this->newline.'-->'.$this->newline;
  14.         return false;
  15.     }
  16.     return true;
  17. }


3.3 Connecting to the SMTP Server


Now what we need to do is connect to the server.
PHP Code: [ Select ]
private function Connect2Server() {

Here we initiate the function. We make this function private since only this class is supposed to have access to the function.
PHP Code: [ Select ]
    // Connect to server
    $this->smtpConnect = fsockopen($this->smtpServer,$this->port,$errno,$error,$this->timeout);
  1.     // Connect to server
  2.     $this->smtpConnect = fsockopen($this->smtpServer,$this->port,$errno,$error,$this->timeout);


Here we actually connect to the SMTP Server using the information provided in the variables declared.
PHP Code: [ Select ]
    $this->logArray['CONNECT_RESPONSE'] = $this->readResponse();

Here we log the response/result of the attempted SMTP connection.
PHP Code: [ Select ]
    if (!is_resource($this->smtpConnect)) {
        return false;
    }
  1.     if (!is_resource($this->smtpConnect)) {
  2.         return false;
  3.     }

If the connection failed, we return false. Returning something at this point stops the function from continuing and ends the script.
PHP Code: [ Select ]
    $this->logArray['connection'] = "Connection accepted";

If we reached this point, it means that the SMTP server was successfully connected to... lets log it for debug purposes.
PHP Code: [ Select ]
    // Hi, server!
    $this->sendCommand("HELLO {$this->localdomain}");
    $this->logArray['HELLO'] = $this->readResponse();
  1.     // Hi, server!
  2.     $this->sendCommand("HELLO {$this->localdomain}");
  3.     $this->logArray['HELLO'] = $this->readResponse();

Here is where we introduce our site to the SMTP server and store the response from the SMTP server for debug purposes.
PHP Code: [ Select ]
    // Let's know each other
    $this->sendCommand('AUTH LOGIN');
    $this->logArray['AUTH_REQUEST'] = $this->readResponse();
  1.     // Let's know each other
  2.     $this->sendCommand('AUTH LOGIN');
  3.     $this->logArray['AUTH_REQUEST'] = $this->readResponse();

Here is where the script is requesting permission and initiate the username/password phase of the connection process. We are store the response for debug purposes.
PHP Code: [ Select ]
    // My name...
    $this->sendCommand(base64_encode($this->username));
    $this->logArray['REQUEST_USER'] = $this->readResponse();
  1.     // My name...
  2.     $this->sendCommand(base64_encode($this->username));
  3.     $this->logArray['REQUEST_USER'] = $this->readResponse();

We are providing the SMTP server with our username, and store the response for debug purposes.
PHP Code: [ Select ]
    // My password..
    $this->sendCommand(base64_encode($this->password));
    $this->logArray['REQUEST_PASSWD'] = $this->readResponse();
  1.     // My password..
  2.     $this->sendCommand(base64_encode($this->password));
  3.     $this->logArray['REQUEST_PASSWD'] = $this->readResponse();

In this phase, we are sending the password, and then store the response for debug purposes.
PHP Code: [ Select ]
    // If error in response auth...
    if (substr($this->logArray['REQUEST_PASSWD'],0,3)!='235') {
        $this->Error .= 'Authorization error! '.$this->logArray['REQUEST_PASSWD'].$this->newline;
        return false;
    }
  1.     // If error in response auth...
  2.     if (substr($this->logArray['REQUEST_PASSWD'],0,3)!='235') {
  3.         $this->Error .= 'Authorization error! '.$this->logArray['REQUEST_PASSWD'].$this->newline;
  4.         return false;
  5.     }

Here is where we check the result of the login process. We store the error in the error variable and returning false, stopping the script.
PHP Code: [ Select ]
    // "From" mail...
    $this->sendCommand("MAIL FROM: {$this->from}");
    $this->logArray['MAIL_FROM_RESPONSE'] = $this->readResponse();
  1.     // "From" mail...
  2.     $this->sendCommand("MAIL FROM: {$this->from}");
  3.     $this->logArray['MAIL_FROM_RESPONSE'] = $this->readResponse();

Here we tell the SMTP server who the message is sent from and store the response for debug purposes.
PHP Code: [ Select ]
    if (substr($this->logArray['MAIL_FROM_RESPONSE'],0,3)!='250') {
        $this->Error .= 'Mistake in sender\'s address! '.$this->logArray['MAIL_FROM_RESPONSE'].$this->newline;
        return false;
    }
  1.     if (substr($this->logArray['MAIL_FROM_RESPONSE'],0,3)!='250') {
  2.         $this->Error .= 'Mistake in sender\'s address! '.$this->logArray['MAIL_FROM_RESPONSE'].$this->newline;
  3.         return false;
  4.     }

Checking the result of the validation of the 'from' address. If the response isn't correct, we store the error in the error variable and return false, stopping the script.
PHP Code: [ Select ]
    // "To" address
    $this->sendCommand("RCPT TO: {$this->to}");
    $this->logArray['RCPT_TO_RESPONCE'] = $this->readResponse();
  1.     // "To" address
  2.     $this->sendCommand("RCPT TO: {$this->to}");
  3.     $this->logArray['RCPT_TO_RESPONCE'] = $this->readResponse();

Here we tell the SMTP server the address to whom the message was written to. Then we store the response for debug purposes.
PHP Code: [ Select ]
    if(substr($this->logArray['RCPT_TO_RESPONCE'],0,3) != '250')
    {
        $this->Error .= 'Mistake in reciepent address! '.$this->logArray['RCPT_TO_RESPONCE'].$this->newline;
        return false;
    }
  1.     if(substr($this->logArray['RCPT_TO_RESPONCE'],0,3) != '250')
  2.     {
  3.         $this->Error .= 'Mistake in reciepent address! '.$this->logArray['RCPT_TO_RESPONCE'].$this->newline;
  4.         return false;
  5.     }

Here we are checking the result of the validation of the recipient's email address. Storing the error and returning false, stopping the script.
PHP Code: [ Select ]
    // Send data to server
    $this->sendCommand('DATA');
    $this->logArray['DATA_RESPONSE'] = $this->readResponse();
  1.     // Send data to server
  2.     $this->sendCommand('DATA');
  3.     $this->logArray['DATA_RESPONSE'] = $this->readResponse();

Here we send the data and storing the response for debug purposes.
PHP Code: [ Select ]
    // Send mail message
    if (!$this->sendMail()) return false;
  1.     // Send mail message
  2.     if (!$this->sendMail()) return false;

Here we send the mail message... we check specifically for failure, and if it failed, returning false, which enables you to write your own failure message.
PHP Code: [ Select ]
    // Good bye server! =)
    $this->sendCommand('QUIT');
    $this->logArray['QUIT_RESPONSE'] = $this->readResponse();
  1.     // Good bye server! =)
  2.     $this->sendCommand('QUIT');
  3.     $this->logArray['QUIT_RESPONSE'] = $this->readResponse();

Here we are preparing to disconnect from the SMTP server. Storing the response for debug purposes.
PHP Code: [ Select ]
    // Close smtp connect
    fclose($this->smtpConnect);
    return true;
}
  1.     // Close smtp connect
  2.     fclose($this->smtpConnect);
  3.     return true;
  4. }

Here we are actually disconnecting from the SMTP server. Since we got to this point, the mail was sent, and everything worked correctly, so we are returning true for success.

The reason we have the 'QUIT' command and then the disconnection, instead of just disconnecting, is the same reason why you press 'Shut Down' to turn your computer off, instead of just pulling the plug. (At least that's how I see it).

Now, here is that function in it's entirety.
PHP Code: [ Select ]
private function Connect2Server() {
    // Connect to server
    $this->smtpConnect = fsockopen($this->smtpServer,$this->port,$errno,$error,$this->timeout);
    $this->logArray['CONNECT_RESPONSE'] = $this->readResponse();
 
    if (!is_resource($this->smtpConnect)) {
        return false;
    }
    $this->logArray['connection'] = "Connection accepted";
    // Hi, server!
    $this->sendCommand("HELLO {$this->localdomain}");
    $this->logArray['HELLO'] = $this->readResponse();
    // Let's know each other
    $this->sendCommand('AUTH LOGIN');
    $this->logArray['AUTH_REQUEST'] = $this->readResponse();
    // My name...
    $this->sendCommand(base64_encode($this->username));
    $this->logArray['REQUEST_USER'] = $this->readResponse();
    // My password..
    $this->sendCommand(base64_encode($this->password));
    $this->logArray['REQUEST_PASSWD'] = $this->readResponse();
    // If error in response auth...
    if (substr($this->logArray['REQUEST_PASSWD'],0,3)!='235') {
        $this->Error .= 'Authorization error! '.$this->logArray['REQUEST_PASSWD'].$this->newline;
        return false;
    }
    // "From" mail...
    $this->sendCommand("MAIL FROM: {$this->from}");
    $this->logArray['MAIL_FROM_RESPONSE'] = $this->readResponse();
    if (substr($this->logArray['MAIL_FROM_RESPONSE'],0,3)!='250') {
        $this->Error .= 'Mistake in sender\'s address! '.$this->logArray['MAIL_FROM_RESPONSE'].$this->newline;
        return false;
    }
    // "To" address
    $this->sendCommand("RCPT TO: {$this->to}");
    $this->logArray['RCPT_TO_RESPONCE'] = $this->readResponse();
    if(substr($this->logArray['RCPT_TO_RESPONCE'],0,3) != '250')
    {
        $this->Error .= 'Mistake in reciepent address! '.$this->logArray['RCPT_TO_RESPONCE'].$this->newline;
    }
    // Send data to server
    $this->sendCommand('DATA');
    $this->logArray['DATA_RESPONSE'] = $this->readResponse();
    // Send mail message
    if (!$this->sendMail()) return false;
    // Good bye server! =)
    $this->sendCommand('QUIT');
    $this->logArray['QUIT_RESPONSE'] = $this->readResponse();
    // Close smtp connect
    fclose($this->smtpConnect);
    return true;
}
  1. private function Connect2Server() {
  2.     // Connect to server
  3.     $this->smtpConnect = fsockopen($this->smtpServer,$this->port,$errno,$error,$this->timeout);
  4.     $this->logArray['CONNECT_RESPONSE'] = $this->readResponse();
  5.  
  6.     if (!is_resource($this->smtpConnect)) {
  7.         return false;
  8.     }
  9.     $this->logArray['connection'] = "Connection accepted";
  10.     // Hi, server!
  11.     $this->sendCommand("HELLO {$this->localdomain}");
  12.     $this->logArray['HELLO'] = $this->readResponse();
  13.     // Let's know each other
  14.     $this->sendCommand('AUTH LOGIN');
  15.     $this->logArray['AUTH_REQUEST'] = $this->readResponse();
  16.     // My name...
  17.     $this->sendCommand(base64_encode($this->username));
  18.     $this->logArray['REQUEST_USER'] = $this->readResponse();
  19.     // My password..
  20.     $this->sendCommand(base64_encode($this->password));
  21.     $this->logArray['REQUEST_PASSWD'] = $this->readResponse();
  22.     // If error in response auth...
  23.     if (substr($this->logArray['REQUEST_PASSWD'],0,3)!='235') {
  24.         $this->Error .= 'Authorization error! '.$this->logArray['REQUEST_PASSWD'].$this->newline;
  25.         return false;
  26.     }
  27.     // "From" mail...
  28.     $this->sendCommand("MAIL FROM: {$this->from}");
  29.     $this->logArray['MAIL_FROM_RESPONSE'] = $this->readResponse();
  30.     if (substr($this->logArray['MAIL_FROM_RESPONSE'],0,3)!='250') {
  31.         $this->Error .= 'Mistake in sender\'s address! '.$this->logArray['MAIL_FROM_RESPONSE'].$this->newline;
  32.         return false;
  33.     }
  34.     // "To" address
  35.     $this->sendCommand("RCPT TO: {$this->to}");
  36.     $this->logArray['RCPT_TO_RESPONCE'] = $this->readResponse();
  37.     if(substr($this->logArray['RCPT_TO_RESPONCE'],0,3) != '250')
  38.     {
  39.         $this->Error .= 'Mistake in reciepent address! '.$this->logArray['RCPT_TO_RESPONCE'].$this->newline;
  40.     }
  41.     // Send data to server
  42.     $this->sendCommand('DATA');
  43.     $this->logArray['DATA_RESPONSE'] = $this->readResponse();
  44.     // Send mail message
  45.     if (!$this->sendMail()) return false;
  46.     // Good bye server! =)
  47.     $this->sendCommand('QUIT');
  48.     $this->logArray['QUIT_RESPONSE'] = $this->readResponse();
  49.     // Close smtp connect
  50.     fclose($this->smtpConnect);
  51.     return true;
  52. }

3.4 The Function that Sends


This is the function that does the actual sending of the email message.
PHP Code: [ Select ]
private function sendMail() {

Once again we create this function as private.
PHP Code: [ Select ]
    $this->sendHeaders();

Here is where we initiate the function that creates and sends the headers of the mail message
PHP Code: [ Select ]
    $this->sendCommand($this->message);
    $this->sendCommand('.');
    $this->logArray['SEND_DATA_RESPONSE'] = $this->readResponse();
  1.     $this->sendCommand($this->message);
  2.     $this->sendCommand('.');
  3.     $this->logArray['SEND_DATA_RESPONSE'] = $this->readResponse();

Here we are sending the data and storing the response for debug purposes.
PHP Code: [ Select ]
    if(substr($this->logArray['SEND_DATA_RESPONSE'],0,3)!='250') {
        $this->Error .= 'Mistake in sending data! '.$this->logArray['SEND_DATA_RESPONSE'].$this->newline;
        return false;
    }
  1.     if(substr($this->logArray['SEND_DATA_RESPONSE'],0,3)!='250') {
  2.         $this->Error .= 'Mistake in sending data! '.$this->logArray['SEND_DATA_RESPONSE'].$this->newline;
  3.         return false;
  4.     }

Here we are checking the sending process for failure. If it failed we would store the error in the variable and return false, stopping the script.
PHP Code: [ Select ]
    return true;
}
  1.     return true;
  2. }

Since we got to this point, the message was sent successfully, so we are returning true for success

Here is that function in it's entirety.
PHP Code: [ Select ]
private function sendMail() {
    $this->sendHeaders();
    $this->sendCommand($this->message);
    $this->sendCommand('.');
    $this->logArray['SEND_DATA_RESPONSE'] = $this->readResponse();
    if(substr($this->logArray['SEND_DATA_RESPONSE'],0,3)!='250') {
        $this->Error .= 'Mistake in sending data! '.$this->logArray['SEND_DATA_RESPONSE'].$this->newline;
        return false;
    }
    return true;
}
  1. private function sendMail() {
  2.     $this->sendHeaders();
  3.     $this->sendCommand($this->message);
  4.     $this->sendCommand('.');
  5.     $this->logArray['SEND_DATA_RESPONSE'] = $this->readResponse();
  6.     if(substr($this->logArray['SEND_DATA_RESPONSE'],0,3)!='250') {
  7.         $this->Error .= 'Mistake in sending data! '.$this->logArray['SEND_DATA_RESPONSE'].$this->newline;
  8.         return false;
  9.     }
  10.     return true;
  11. }


3.5 Reading the responses


We now need to create a function that reads the responses sent to us by the SMTP server.
PHP Code: [ Select ]
// Function read response
private function readResponse() {
  1. // Function read response
  2. private function readResponse() {

Once again... private function
PHP Code: [ Select ]
    $data="";

We initiate the variable... can't add on to a variable without it being set first
PHP Code: [ Select ]
    while($str = fgets($this->smtpConnect,4096))
    {
        $data .= $str;
        if(substr($str,3,1) == " ") { break; }
    }
  1.     while($str = fgets($this->smtpConnect,4096))
  2.     {
  3.         $data .= $str;
  4.         if(substr($str,3,1) == " ") { break; }
  5.     }

We are looping through the response and retrieving the responses
PHP Code: [ Select ]
    return $data;
}
  1.     return $data;
  2. }

We are returning all of the responses that we received from the SMTP server.

Here is the function in it's entirety.
PHP Code: [ Select ]
// Function read response
private function readResponse() {
    $data="";
    while($str = fgets($this->smtpConnect,4096))
    {
        $data .= $str;
        if(substr($str,3,1) == " ") { break; }
    }
    return $data;
}
  1. // Function read response
  2. private function readResponse() {
  3.     $data="";
  4.     while($str = fgets($this->smtpConnect,4096))
  5.     {
  6.         $data .= $str;
  7.         if(substr($str,3,1) == " ") { break; }
  8.     }
  9.     return $data;
  10. }


3.6 Sending our commands


Here is when we get bossy. We need a function to send our commands to the SMTP server.
PHP Code: [ Select ]
// function send command to server
private function sendCommand($string) {
    fputs($this->smtpConnect,$string.$this->newline);
    return ;
}
  1. // function send command to server
  2. private function sendCommand($string) {
  3.     fputs($this->smtpConnect,$string.$this->newline);
  4.     return ;
  5. }

We create a private function, and then send our command. Returning nothing since there is nothing to return.

3.7 Creating those Headers


Now we need to create the headers to be used in that message you sent.
PHP Code: [ Select ]
private function sendHeaders() {
    $this->sendCommand("Date: ".date("D, j M Y G:i:s")." +0700");
    $this->sendCommand("From: <{$this->from}>");
    $this->sendCommand("Reply-To: <{$this->from}>");
    $this->sendCommand("To: <{$this->to}>");
    $this->sendCommand("Subject: {$this->subject}");
    $this->sendCommand("MIME-Version: 1.0");
    $this->sendCommand("Content-Type: text/html; charset={$this->charset}");
    if ($this->contentTransferEncoding) $this->sendCommand("Content-Transfer-Encoding: {$this->contentTransferEncoding}");
    return ;
}
  1. private function sendHeaders() {
  2.     $this->sendCommand("Date: ".date("D, j M Y G:i:s")." +0700");
  3.     $this->sendCommand("From: <{$this->from}>");
  4.     $this->sendCommand("Reply-To: <{$this->from}>");
  5.     $this->sendCommand("To: <{$this->to}>");
  6.     $this->sendCommand("Subject: {$this->subject}");
  7.     $this->sendCommand("MIME-Version: 1.0");
  8.     $this->sendCommand("Content-Type: text/html; charset={$this->charset}");
  9.     if ($this->contentTransferEncoding) $this->sendCommand("Content-Transfer-Encoding: {$this->contentTransferEncoding}");
  10.     return ;
  11. }

Here is that private function that creates the headers. And returns nothing since there is nothing to return.

3.8 Destructing the class


Now what we need to do is destruct the class.
PHP Code: [ Select ]
function __destruct() {
    if (is_resource($this->smtpConnect)) fclose($this->smtpConnect);
}
  1. function __destruct() {
  2.     if (is_resource($this->smtpConnect)) fclose($this->smtpConnect);
  3. }

The purpose of this function is if in any case that the class is stopped before disconnecting from the SMTP server, we would disconnect it here.

3.9 The class in it's entirety


Here is this class in it's entirety (I'm not attaching it, since this forum has this advanced collapsing PHP code block).

Lets save this page as smtp_mail.php
PHP Code: [ Select ]
<?php
class smtp_mail {
    private $smtpServer = 'smtp.gmail.com';
    private $port = '587';
    private $timeout = 30;
    private $username = 'myname@gmail.com';
    private $password = 'mypassword';
    private $username_email = 'myreceivingemail@gmail.com';
    private $newline = "\r\n";
    private $localdomain = 'http://www.mysite.com';
    private $charset = 'windows-1251';
    private $contentTransferEncoding = false;
 
    // Do not change anything below
    private $smtpConnect = false;
    private $to = false;
    private $to_admin = false;
    private $subject = false;
    private $message = false;
    private $headers = false;
    private $logArray = array(); // Array response message for debug
    private $Error = '';
    private $from = false;
 
    public function __construct($to, $subject, $message, $to_admin) {
        $this->to_admin = $to_admin;
        $this->to = (($this->to_admin === false) ? $this->username_email : $to );
        $this->from = (($this->to_admin === false) ? $to : $this->username_email );
        $this->subject = &$subject;
        $this->message = &$message;
 
        // Connect to server
        if(!$this->Connect2Server()) {
            // Display error message
            echo '<pre>'.trim($this->Error).'</pre>'.$this->newline.'<!-- '.$this->newline;
            print_r($this->logArray);
            echo $this->newline.'-->'.$this->newline;
            return false;
        }
        return true;
    }
   
    private function Connect2Server() {
        // Connect to server
        $this->smtpConnect = fsockopen($this->smtpServer,$this->port,$errno,$error,$this->timeout);
        $this->logArray['CONNECT_RESPONSE'] = $this->readResponse();
 
        if (!is_resource($this->smtpConnect)) {
            return false;
        }
        $this->logArray['connection'] = "Connection accepted";
        // Hi, server!
        $this->sendCommand("HELLO {$this->localdomain}");
        $this->logArray['HELLO'] = $this->readResponse();
        // Let's know each other
        $this->sendCommand('AUTH LOGIN');
        $this->logArray['AUTH_REQUEST'] = $this->readResponse();
        // My name...
        $this->sendCommand(base64_encode($this->username));
        $this->logArray['REQUEST_USER'] = $this->readResponse();
        // My password..
        $this->sendCommand(base64_encode($this->password));
        $this->logArray['REQUEST_PASSWD'] = $this->readResponse();
        // If error in response auth...
        if (substr($this->logArray['REQUEST_PASSWD'],0,3)!='235') {
            $this->Error .= 'Authorization error! '.$this->logArray['REQUEST_PASSWD'].$this->newline;
            return false;
        }
        // "From" mail...
        $this->sendCommand("MAIL FROM: {$this->from}");
        $this->logArray['MAIL_FROM_RESPONSE'] = $this->readResponse();
        if (substr($this->logArray['MAIL_FROM_RESPONSE'],0,3)!='250') {
            $this->Error .= 'Mistake in sender\'s address! '.$this->logArray['MAIL_FROM_RESPONSE'].$this->newline;
            return false;
        }
        // "To" address
        $this->sendCommand("RCPT TO: {$this->to}");
        $this->logArray['RCPT_TO_RESPONCE'] = $this->readResponse();
        if(substr($this->logArray['RCPT_TO_RESPONCE'],0,3) != '250')
        {
            $this->Error .= 'Mistake in reciepent address! '.$this->logArray['RCPT_TO_RESPONCE'].$this->newline;
        }
        // Send data to server
        $this->sendCommand('DATA');
        $this->logArray['DATA_RESPONSE'] = $this->readResponse();
        // Send mail message
        if (!$this->sendMail()) return false;
        // Good bye server! =)
        $this->sendCommand('QUIT');
        $this->logArray['QUIT_RESPONSE'] = $this->readResponse();
        // Close smtp connect
        fclose($this->smtpConnect);
        return true;
    }
   
    private function sendMail() {
        $this->sendHeaders();
        $this->sendCommand($this->message);
        $this->sendCommand('.');
        $this->logArray['SEND_DATA_RESPONSE'] = $this->readResponse();
        if(substr($this->logArray['SEND_DATA_RESPONSE'],0,3)!='250') {
            $this->Error .= 'Mistake in sending data! '.$this->logArray['SEND_DATA_RESPONSE'].$this->newline;
            return false;
        }
        return true;
    }
   
    // Function read response
    private function readResponse() {
        $data="";
        while($str = fgets($this->smtpConnect,4096))
        {
            $data .= $str;
            if(substr($str,3,1) == " ") { break; }
        }
        return $data;
    }
   
    // function send command to server
    private function sendCommand($string) {
        fputs($this->smtpConnect,$string.$this->newline);
        return ;
    }
   
    // function send headers
    private function sendHeaders() {
        $this->sendCommand("Date: ".date("D, j M Y G:i:s")." +0700");
        $this->sendCommand("From: <{$this->from}>");
        $this->sendCommand("Reply-To: <{$this->from}>");
        $this->sendCommand("To: <{$this->to}>");
        $this->sendCommand("Subject: {$this->subject}");
        $this->sendCommand("MIME-Version: 1.0");
        $this->sendCommand("Content-Type: text/html; charset={$this->charset}");
        if ($this->contentTransferEncoding) $this->sendCommand("Content-Transfer-Encoding: {$this->contentTransferEncoding}");
        return ;
    }
   
    function __destruct() {
        if (is_resource($this->smtpConnect)) fclose($this->smtpConnect);
    }
}
?>
  1. <?php
  2. class smtp_mail {
  3.     private $smtpServer = 'smtp.gmail.com';
  4.     private $port = '587';
  5.     private $timeout = 30;
  6.     private $username = 'myname@gmail.com';
  7.     private $password = 'mypassword';
  8.     private $username_email = 'myreceivingemail@gmail.com';
  9.     private $newline = "\r\n";
  10.     private $localdomain = 'http://www.mysite.com';
  11.     private $charset = 'windows-1251';
  12.     private $contentTransferEncoding = false;
  13.  
  14.     // Do not change anything below
  15.     private $smtpConnect = false;
  16.     private $to = false;
  17.     private $to_admin = false;
  18.     private $subject = false;
  19.     private $message = false;
  20.     private $headers = false;
  21.     private $logArray = array(); // Array response message for debug
  22.     private $Error = '';
  23.     private $from = false;
  24.  
  25.     public function __construct($to, $subject, $message, $to_admin) {
  26.         $this->to_admin = $to_admin;
  27.         $this->to = (($this->to_admin === false) ? $this->username_email : $to );
  28.         $this->from = (($this->to_admin === false) ? $to : $this->username_email );
  29.         $this->subject = &$subject;
  30.         $this->message = &$message;
  31.  
  32.         // Connect to server
  33.         if(!$this->Connect2Server()) {
  34.             // Display error message
  35.             echo '<pre>'.trim($this->Error).'</pre>'.$this->newline.'<!-- '.$this->newline;
  36.             print_r($this->logArray);
  37.             echo $this->newline.'-->'.$this->newline;
  38.             return false;
  39.         }
  40.         return true;
  41.     }
  42.    
  43.     private function Connect2Server() {
  44.         // Connect to server
  45.         $this->smtpConnect = fsockopen($this->smtpServer,$this->port,$errno,$error,$this->timeout);
  46.         $this->logArray['CONNECT_RESPONSE'] = $this->readResponse();
  47.  
  48.         if (!is_resource($this->smtpConnect)) {
  49.             return false;
  50.         }
  51.         $this->logArray['connection'] = "Connection accepted";
  52.         // Hi, server!
  53.         $this->sendCommand("HELLO {$this->localdomain}");
  54.         $this->logArray['HELLO'] = $this->readResponse();
  55.         // Let's know each other
  56.         $this->sendCommand('AUTH LOGIN');
  57.         $this->logArray['AUTH_REQUEST'] = $this->readResponse();
  58.         // My name...
  59.         $this->sendCommand(base64_encode($this->username));
  60.         $this->logArray['REQUEST_USER'] = $this->readResponse();
  61.         // My password..
  62.         $this->sendCommand(base64_encode($this->password));
  63.         $this->logArray['REQUEST_PASSWD'] = $this->readResponse();
  64.         // If error in response auth...
  65.         if (substr($this->logArray['REQUEST_PASSWD'],0,3)!='235') {
  66.             $this->Error .= 'Authorization error! '.$this->logArray['REQUEST_PASSWD'].$this->newline;
  67.             return false;
  68.         }
  69.         // "From" mail...
  70.         $this->sendCommand("MAIL FROM: {$this->from}");
  71.         $this->logArray['MAIL_FROM_RESPONSE'] = $this->readResponse();
  72.         if (substr($this->logArray['MAIL_FROM_RESPONSE'],0,3)!='250') {
  73.             $this->Error .= 'Mistake in sender\'s address! '.$this->logArray['MAIL_FROM_RESPONSE'].$this->newline;
  74.             return false;
  75.         }
  76.         // "To" address
  77.         $this->sendCommand("RCPT TO: {$this->to}");
  78.         $this->logArray['RCPT_TO_RESPONCE'] = $this->readResponse();
  79.         if(substr($this->logArray['RCPT_TO_RESPONCE'],0,3) != '250')
  80.         {
  81.             $this->Error .= 'Mistake in reciepent address! '.$this->logArray['RCPT_TO_RESPONCE'].$this->newline;
  82.         }
  83.         // Send data to server
  84.         $this->sendCommand('DATA');
  85.         $this->logArray['DATA_RESPONSE'] = $this->readResponse();
  86.         // Send mail message
  87.         if (!$this->sendMail()) return false;
  88.         // Good bye server! =)
  89.         $this->sendCommand('QUIT');
  90.         $this->logArray['QUIT_RESPONSE'] = $this->readResponse();
  91.         // Close smtp connect
  92.         fclose($this->smtpConnect);
  93.         return true;
  94.     }
  95.    
  96.     private function sendMail() {
  97.         $this->sendHeaders();
  98.         $this->sendCommand($this->message);
  99.         $this->sendCommand('.');
  100.         $this->logArray['SEND_DATA_RESPONSE'] = $this->readResponse();
  101.         if(substr($this->logArray['SEND_DATA_RESPONSE'],0,3)!='250') {
  102.             $this->Error .= 'Mistake in sending data! '.$this->logArray['SEND_DATA_RESPONSE'].$this->newline;
  103.             return false;
  104.         }
  105.         return true;
  106.     }
  107.    
  108.     // Function read response
  109.     private function readResponse() {
  110.         $data="";
  111.         while($str = fgets($this->smtpConnect,4096))
  112.         {
  113.             $data .= $str;
  114.             if(substr($str,3,1) == " ") { break; }
  115.         }
  116.         return $data;
  117.     }
  118.    
  119.     // function send command to server
  120.     private function sendCommand($string) {
  121.         fputs($this->smtpConnect,$string.$this->newline);
  122.         return ;
  123.     }
  124.    
  125.     // function send headers
  126.     private function sendHeaders() {
  127.         $this->sendCommand("Date: ".date("D, j M Y G:i:s")." +0700");
  128.         $this->sendCommand("From: <{$this->from}>");
  129.         $this->sendCommand("Reply-To: <{$this->from}>");
  130.         $this->sendCommand("To: <{$this->to}>");
  131.         $this->sendCommand("Subject: {$this->subject}");
  132.         $this->sendCommand("MIME-Version: 1.0");
  133.         $this->sendCommand("Content-Type: text/html; charset={$this->charset}");
  134.         if ($this->contentTransferEncoding) $this->sendCommand("Content-Transfer-Encoding: {$this->contentTransferEncoding}");
  135.         return ;
  136.     }
  137.    
  138.     function __destruct() {
  139.         if (is_resource($this->smtpConnect)) fclose($this->smtpConnect);
  140.     }
  141. }
  142. ?>


4.0 Class Usage


Now we want a simple way to use that SMTP class.
PHP Code: [ Select ]
if(new smtp_mail($to, $subject, $message, true))
{
    echo 'Your message has being sent successfully.';
}
else
{
    echo 'There was a problem sending the message';
    // Possibly log this for your reference
}
  1. if(new smtp_mail($to, $subject, $message, true))
  2. {
  3.     echo 'Your message has being sent successfully.';
  4. }
  5. else
  6. {
  7.     echo 'There was a problem sending the message';
  8.     // Possibly log this for your reference
  9. }

Simple, right?

5.0 The Form


Now we need the form to use that people are going to use to fill out to send their message.

Lets save this page as contact.html
HTML Code: [ Select ]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <title>Contact Form</title>
        <style type="text/css">
            #contact_form {
                width: 100%;
            }
           
            .form_col {
                float: left;
                margin-left: 10px;
            }
        </style>
    </head>
    <body>
        <div id="contact_form">
            <form action="contact.php" method="post">
                <div class="form_col">
                    <p>Name:<br>
                    Email Address:<br>
                    To:<br>
                    Subject:<br>
                    Message:</p>
                </div>
                <div class="form_col">
                    <p><input type="text" name="name" size="30"> Required<br>
                    <input type="text" name="email" size="30"> Required<br>
                    <input type="text" name="to" size="30"> To Administrator <input type="checkbox" name="to2"><br>
                    <input type="text" name="subject" size="30"> Required<br>
                    <textarea name="message" cols="50" rows="10"></textarea><br>
                    <input type="submit" name="submit" value="Submit"> <input type="reset" value="Reset"> The Message is Required</p>
                </div>
            </form>
        </div>
        <p style="clear: both;"></p>
    </body>
</html>
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  2. <html>
  3.     <head>
  4.         <title>Contact Form</title>
  5.         <style type="text/css">
  6.             #contact_form {
  7.                 width: 100%;
  8.             }
  9.            
  10.             .form_col {
  11.                 float: left;
  12.                 margin-left: 10px;
  13.             }
  14.         </style>
  15.     </head>
  16.     <body>
  17.         <div id="contact_form">
  18.             <form action="contact.php" method="post">
  19.                 <div class="form_col">
  20.                     <p>Name:<br>
  21.                     Email Address:<br>
  22.                     To:<br>
  23.                     Subject:<br>
  24.                     Message:</p>
  25.                 </div>
  26.                 <div class="form_col">
  27.                     <p><input type="text" name="name" size="30"> Required<br>
  28.                     <input type="text" name="email" size="30"> Required<br>
  29.                     <input type="text" name="to" size="30"> To Administrator <input type="checkbox" name="to2"><br>
  30.                     <input type="text" name="subject" size="30"> Required<br>
  31.                     <textarea name="message" cols="50" rows="10"></textarea><br>
  32.                     <input type="submit" name="submit" value="Submit"> <input type="reset" value="Reset"> The Message is Required</p>
  33.                 </div>
  34.             </form>
  35.         </div>
  36.         <p style="clear: both;"></p>
  37.     </body>
  38. </html>

That's just a nice styled form for you to use with this class.

5.1 The Form Processor


Now lets create a PHP page which processes the form above.

Lets save this page as contact.php
PHP Code: [ Select ]
<?php
// Checking if the form was really submitted
if(isset($_POST['submit']))
{
    // We need to initiate the error array
    $error = array();
   
    // Here we are checking if their name was filled in.
    if(empty($_POST['name']))
    {
        // The name field was left empty
        $error[] = "You need to enter a valid name.";
    }
   
    // Checking if a valid email address was filled in.
    if(!preg_match("/(?:[a-zA-Z0-9_\'\^\&\/\+\-])+(?:\.(?:[a-zA-Z0-9_\'\^\&\/\+\-])+)*@(?:(?:\[?(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\.){3}(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\]?)|(?:[a-zA-Z0-9-]+\.)+(?:[a-zA-Z]){2,}\.?)/", $_POST['email']))
    {
        // An invalid email address was filled in.
        $error[] = "You need to enter a valid email address.";
    }
   
    // We need to determine the recipient of the message
    if(isset($_POST['to_admin']))
    {
        // Even if the to field was given a different email address, this would over-ride that address and be sent to admin.
        $to_admin = true;
        $to = false;
    }
    elseif(preg_match("/(?:[a-zA-Z0-9_\'\^\&\/\+\-])+(?:\.(?:[a-zA-Z0-9_\'\^\&\/\+\-])+)*@(?:(?:\[?(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\.){3}(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\]?)|(?:[a-zA-Z0-9-]+\.)+(?:[a-zA-Z]){2,}\.?)/", $_POST['to']))
    {
        // If the process reaches here, then the message would be sent to the address put in the to field
        $to_admin = false;
        $to = $_POST['to'];
    }
    else
    {
        // There was an error... it's not sent to the admin OR to anyone...
        $error[] = "You need a valid recipient's (to) email address.";
    }
   
    // Now we need to validate the subject of the message
    if(strlen($_POST['subject']) < 5)
    {
        // The message is under 5 characters.
        $error[] = "The subject needs to be greater then 5 characters";
    }
   
    // Validating the actuall message
    if(strlen($_POST['message']) < 5)
    {
        $error[] = "The message needs to be greater then 5 characters";
    }
   
    // Counting the number of errors there was in the form submittion
    if(count($error) > 0)
    {
        // There were errors... we can't send a message with errors in the form submittion.
       
        // Looping through each error and providing a good list of errors for the user.
        $errors = "<ol>";
        foreach($error as $er)
        {
            $errors .= "<li>{$er}</li>\n";
        }
        $errors .= "</ol>";
       
        echo $errors;
    }
    else
    {
        // There were no errors, lets submit the actual message
        if(new smtp_mail($to, $_POST['subject'], $_POST['message'], $to_admin))
        {
            echo "The mail was sent successfully.";
        }
        else
        {
            echo "There was a problem sending the message.";
        }
    }
}
?>
  1. <?php
  2. // Checking if the form was really submitted
  3. if(isset($_POST['submit']))
  4. {
  5.     // We need to initiate the error array
  6.     $error = array();
  7.    
  8.     // Here we are checking if their name was filled in.
  9.     if(empty($_POST['name']))
  10.     {
  11.         // The name field was left empty
  12.         $error[] = "You need to enter a valid name.";
  13.     }
  14.    
  15.     // Checking if a valid email address was filled in.
  16.     if(!preg_match("/(?:[a-zA-Z0-9_\'\^\&\/\+\-])+(?:\.(?:[a-zA-Z0-9_\'\^\&\/\+\-])+)*@(?:(?:\[?(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\.){3}(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\]?)|(?:[a-zA-Z0-9-]+\.)+(?:[a-zA-Z]){2,}\.?)/", $_POST['email']))
  17.     {
  18.         // An invalid email address was filled in.
  19.         $error[] = "You need to enter a valid email address.";
  20.     }
  21.    
  22.     // We need to determine the recipient of the message
  23.     if(isset($_POST['to_admin']))
  24.     {
  25.         // Even if the to field was given a different email address, this would over-ride that address and be sent to admin.
  26.         $to_admin = true;
  27.         $to = false;
  28.     }
  29.     elseif(preg_match("/(?:[a-zA-Z0-9_\'\^\&\/\+\-])+(?:\.(?:[a-zA-Z0-9_\'\^\&\/\+\-])+)*@(?:(?:\[?(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\.){3}(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\]?)|(?:[a-zA-Z0-9-]+\.)+(?:[a-zA-Z]){2,}\.?)/", $_POST['to']))
  30.     {
  31.         // If the process reaches here, then the message would be sent to the address put in the to field
  32.         $to_admin = false;
  33.         $to = $_POST['to'];
  34.     }
  35.     else
  36.     {
  37.         // There was an error... it's not sent to the admin OR to anyone...
  38.         $error[] = "You need a valid recipient's (to) email address.";
  39.     }
  40.    
  41.     // Now we need to validate the subject of the message
  42.     if(strlen($_POST['subject']) < 5)
  43.     {
  44.         // The message is under 5 characters.
  45.         $error[] = "The subject needs to be greater then 5 characters";
  46.     }
  47.    
  48.     // Validating the actuall message
  49.     if(strlen($_POST['message']) < 5)
  50.     {
  51.         $error[] = "The message needs to be greater then 5 characters";
  52.     }
  53.    
  54.     // Counting the number of errors there was in the form submittion
  55.     if(count($error) > 0)
  56.     {
  57.         // There were errors... we can't send a message with errors in the form submittion.
  58.        
  59.         // Looping through each error and providing a good list of errors for the user.
  60.         $errors = "<ol>";
  61.         foreach($error as $er)
  62.         {
  63.             $errors .= "<li>{$er}</li>\n";
  64.         }
  65.         $errors .= "</ol>";
  66.        
  67.         echo $errors;
  68.     }
  69.     else
  70.     {
  71.         // There were no errors, lets submit the actual message
  72.         if(new smtp_mail($to, $_POST['subject'], $_POST['message'], $to_admin))
  73.         {
  74.             echo "The mail was sent successfully.";
  75.         }
  76.         else
  77.         {
  78.             echo "There was a problem sending the message.";
  79.         }
  80.     }
  81. }
  82. ?>


5.2 The Magic Function


This is not necessary, but this is what I always use so I'll suggest it here.

I always use the Magic function __autoload() to load classes. This saves me 1 line every time I want to use a class. This way, I don't have to include the PHP file that holds the class... it __autoload()s.

In order for it to work properly, the PHP file needs to be saved the same way that the class is named... so in this case, the class name is smtp_mail and it's saved as smtp_mail.php. So here is that function.
PHP Code: [ Select ]
function __autoload($class_name) {
    if(file_exists('includes/' . $class_name . '.php'))
    {
        require_once 'includes/' . $class_name . '.php';
    }
}
  1. function __autoload($class_name) {
  2.     if(file_exists('includes/' . $class_name . '.php'))
  3.     {
  4.         require_once 'includes/' . $class_name . '.php';
  5.     }
  6. }

What I have this function do is check if that page exist in the includes/ directory... this means, that when I start this class it would look for [/b]includes/smtp_mail.php[/b].

This means that the directory structure should look like the following:
  • includes/smtp_mail.php
  • contact.html
  • contact.php

Another thing that I would recommend doing is having a global page that would be included into every page all the time. Have a look at this tutorial to understand more on what I'm talking here.

In that configuration file, you would put this magic function. If that tip is to come into play here, then the directory structure would change to:

  • includes/smtp_mail.php
  • includes/config.php
  • contact.html
  • contact.php

So, if you look at the line where it would include the smtp_mail class (in contact.php):
PHP Code: [ Select ]
        if(new smtp_mail($to, $_POST['subject'], $_POST['message'], $to_admin))

You see that it's instantiate a new object 'smtp_mail' without me including 'smtp_mail.php'. When the PHP parser gets to this line it would attempt to include 'includes/smtp_mail.php' to be able to instantiate the object. This is the beauty of magic functions.

If you don't want to use the magic function, simply include 'smtp_mail.php' into contact.php. Remember to include 'smtp_mail.php' right before the line that uses that function. (The PHP code block right above this).
PHP Code: [ Select ]
include_once 'includes/smtp_mail.php';


6.0 Conclusion


It is (in most cases) invaluable to have a way to send email messages to your users, be it for newsletters or simply updates or whatever you need to send a message for, you now got a fairly advanced way of sending messages using an SMTP server.
  • Anonymous
  • Bot
  • No Avatar
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post 3+ Months Ago

  • Bogey
  • Genius
  • Genius
  • Bogey
  • Posts: 8388
  • Loc: USA

Post 3+ Months Ago

I just found where I got it from...

phpclasses.org class page
  • Mark709
  • Novice
  • Novice
  • Mark709
  • Posts: 22

Post 3+ Months Ago

Must say this article is wonderful - sadly I am only a beginner yet even I can see that if I study it much benefit will come to me - so THANK YOU for your efforts and posting it for us all.
  • spork
  • Brewmaster
  • Silver Member
  • User avatar
  • Posts: 6251
  • Loc: Seattle, WA

Post 3+ Months Ago

I don't think you quite understand the purpose of constructors and destructors in this tutorial. Constructors are called whenever a new object is created; their purpose is to initialize the data members and set up the object to be used by the caller. Never should you be returning anything from a constructor; the nature of the function is to return the object being created.

The other problem is that you're using object creation as a method call, when really you should be properly constructing the object and then allowing the caller to take action with it. Invoking the mail() functionality at instantiation time isn't right; I should be able to create an smtp_mail object and then choose when the mail is actually sent.

The purpose of a destructor isn't to take action "in case the class is stopped"; classes cannot "stop" or "go" (threads and processes can, but that's a different topic). The purpose of the destructor is to clean up after the object when it is either directly deleted or goes out of scope (or in the case of managed languages, when it gets garbage collected).

I also see bits of HTML and calls to various output functions littered throughout the class, which tightly couples the class to whatever application the user plans to use it in. It would be better to allow the user to read/update results via accessors and mutators such that the application using this class can output the data as it sees fit.

For this class to be useful in an application, it should conform to an interface that would allow me to use it like this:

PHP Code: [ Select ]
<?php
 
$myMailer = new SmtpMailer(new SmtpMailerCredentials(...));
 
// a class such as SmtpMailerCredentials could help
// organize and decouple the non-essential aspects of
// the mail from the mailer class
 
// don't assume only one recipient
$myMailer->addToAddress("someone@domain.com");
$myMailer->addToAddress("someoneelse@domain.com");
 
// ...and don't assume everyone will be on the "to" line!
$myMailer->addCcAddress("athirdperson@domain.com");
 
$myMailer->setSubject("This is a test message");
$myMailer->setBody("This is the body of the message.");
 
// do some other stuff. perhaps add this mailer
// object to a queue of mail to be sent, or do
// whatever else I need to do before the email goes out
 
// now I choose exactly when to send the mail
$mailer->send();
 
?<
  1. <?php
  2.  
  3. $myMailer = new SmtpMailer(new SmtpMailerCredentials(...));
  4.  
  5. // a class such as SmtpMailerCredentials could help
  6. // organize and decouple the non-essential aspects of
  7. // the mail from the mailer class
  8.  
  9. // don't assume only one recipient
  10. $myMailer->addToAddress("someone@domain.com");
  11. $myMailer->addToAddress("someoneelse@domain.com");
  12.  
  13. // ...and don't assume everyone will be on the "to" line!
  14. $myMailer->addCcAddress("athirdperson@domain.com");
  15.  
  16. $myMailer->setSubject("This is a test message");
  17. $myMailer->setBody("This is the body of the message.");
  18.  
  19. // do some other stuff. perhaps add this mailer
  20. // object to a queue of mail to be sent, or do
  21. // whatever else I need to do before the email goes out
  22.  
  23. // now I choose exactly when to send the mail
  24. $mailer->send();
  25.  
  26. ?<
  • Bogey
  • Genius
  • Genius
  • Bogey
  • Posts: 8388
  • Loc: USA

Post 3+ Months Ago

Thanks for the review Spork. I kind of remember creating the class from a jumble of code written as one function (I might have mistaken this class for another). I just found it in my class depository directory on my computer and since it works perfectly for me (I can only make beginner classes work :lol: I'm not so advanced :( ) so I decided to make a walk-through tutorial.

I'll fix it up soon though to comply with your suggested interface and changing some bits of code to fix the problems that you posted. Thanks for the heads up.
  • pagebot
  • Novice
  • Novice
  • pagebot
  • Posts: 16
  • Loc: USA

Post 3+ Months Ago

Very nice tutorial, can i send attachments this way and how can i block certain extensions? Thanks
  • Mark709
  • Novice
  • Novice
  • Mark709
  • Posts: 22

Post 3+ Months Ago

Reviewing this article from Bogey still makes me realize how lucky we are to have Members like Bogey and Spork and others (nameless) who care enough about others to write such a WELL - CONSTRUCTED and clear article.

If you have the time might you also consider - including - how to use the above code and INSERT - a capability to run this as
1. a CRON job
2. to send 1 email every 10 seconds
and/or (which ever is the lesser - important as server needs change from one Host Co to another)
3. a maximum of ... emails per hour

REASON - there are many, many users who are continually with problems around these 3 items and as yet I have not seen such a CLEAR EXPLANATION of a way to get around the problems as many complain their cron stops (at say 500 emails in the first hour) when say their job is to send 5,000 emails - their plight is how to re-start without doing/sending the first 500 emails a second time.

Would appreciate your ideas on how to fix these sorts of issues and thank you so much for the explanations of EACH segment - you are a great teacher and example for us "newbies"

Post Information

  • Total Posts in this topic: 8 posts
  • Moderator: Tutorial Writers
  • Users browsing this forum: No registered users and 2 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.