You need to know the protocols!
Real coder know the protocols and don't rely on tools and silly functions like the mail function in PHP. The SMTP protocol is easy to understand and use. Just for entertainment I send plain text emails using telnet only by connecting directly to the target MX agent.
A while ago I published a function which would allow you to verify any mailbox you wanted, with pretty good success rate. The function used the getmxrr function in *NIX PHP to get the SMTP relay agent for a mailbox.
How sending an email works:
The SMTP protocol is like real life: anyone can talk and anyone can hear and anyone can ask anyone to deliver a message on his behalf. Same rules apply as in real life: a degree of confidence is required.
1. Sending emails using your own server:
Let's say your address is sample@example.com and you SMTP server is mail.example.com. If you want to send a message method one it to connect to your own server and send the message to itself asking it to relay it for you. So you say to your email server:
U: Hey server! Send this out for me.
S: I'll do it when I have the time.
Later on you will find a notice of failure in your mailbox. If you don't find one then the message might have gone through.
2. Sending emails directly to their server:
Let's say your address is sample@example.com and you SMTP server is mail.example.com. And you want to send an email to dude@sample.com who has the SMTP server: mail.sample.com. You can use DNS MX Records Query (or getmxrr function in PHP) and find out the mail server of dude@sample.com. And then you can connect to it and send the email directly.
U: Hey server! Here's some mail for a mailbox you work for.
S: Oh thanks! Who's it for?
U: dude@sample.com
S: Sorry this mailbox does not exist here or Ok! Got IT!
Failure is known instantly when you send emails directly to their servers.
Sending directly is better:
It's easier to use your own server but sometime direct sending is better. It's better because you get an instant error and you don't need login credentials to send an email to the owner SMTP server. So if the mailbox you send for is hosted on that mail server, that server should not reject you. Spam filters are another story.
When you use relay agents you may need login (AUTH) details for them to send emails. This is done in order to restrict spam and ensure only those who have an account on that server can use it to send emails.
Remember: Step1 will always contain Step2. If you send emails to your own server, your own server will work Step2 out and query the MX agent for the destination address and send it again to it.
I'm pretty sure you didn't understand anything:)
So let's get on with the code. The below code show how you use this and after if you will find the SMTP PHP Class itself!
<?
$smtp=new eSmtp("mail.your-server.com",25);
$smtp->setAuth("smtp_auth_user","smtp_auth_pass");
$smtp->setFrom("Dude","dude@your-server.com");
$smtp->addHeader("Bcc","");
$smtp->addHeader("Cc","");
$smtp->isMimeOn=1;
$smtp->addRecipient("Subscriber","subscriber@subscriber-server.com","to");
$smtp->addRecipient("Subscriber1","subscriber1@subscriber1-server.com","to");
$smtp->addRecipient("Subscriber2","subscriber2@subscriber2-server.com","cc");
$smtp->addRecipient("Subscriber3","subscriber3@subscriber3-server.com","bcc");
$smtp->addAttachment($_SERVER['DOCUMENT_ROOT']."/attach.zip","attachment.zip");
$smtp->setSubject("subject");
$smtp->setBody("body");
$smtp->isDebug=0;
if($smtp->connect()){
$success = $smtp->send();
$smtp->disconnect();
}
?>
The SMTP PHP Class
The _functions are internal and should NEVER be used! So use them at your own risk.
<?
class eSmtp{
var $smtpServer = "";
var $smtpPort = 25;
var $lstAttachs = array();
var $lstRecipients = array();
var $lstHeaders = array();
var $authUser = "";
var $authPass = "";
var $replyName = "";
var $replyMail = "";
var $fromName = "";
var $fromMail = "";
var $isMimeOn = 1;
var $isDebug = 0;
var $isHtml = 0;
var $msgSubject = "";
var $msgBody = "";
var $smtpSocket = 0;
function eSmtp($smtpServer=false,$smtpPort=25){
define("EOL","\r\n");
define("MSG_END","\r\n.\r\n");
define("EOH","\r\n\r\n");
define("SEP","\r\n--#BOUNDARY#--");
define("EOM","QUIT\r\n\0");
$this->smtpServer = (($smtpServer!==false) ? $smtpServer : $_SERVER["LOCAL_ADDR"]);
$this->smtpPort = $smtpPort;
}
function setSubject($msgSubject){
$this->msgSubject = $msgSubject;
}
function setBody($msgBody){
$this->msgBody = $msgBody;
}
function setFrom($fromName,$fromMail){
$this->fromName = $fromName;
$this->fromMail = $fromMail;
}
function setReplyTo($reply2Name,$reply2Mail){
$this->replyName = $reply2Name;
$this->replyMail = $reply2Mail;
}
function addAttachment($filePath,$fileName){
$filePath = str_replace("\\","/",$filePath);
if(!isset($fileName)){
$fileName = substr(strrchr($filePath,'/'),1);
}
$fileExtension = substr(strrchr($fileName,'.'),1);
$mimeType = "application/octet-stream";
if(isset($MimeTypes[$fileExtension]))
$mimeType=$MimeTypes[$fileExtension];
return $this->attachFile($filePath,$fileName,$mimeType);
}
function attachFile($filePath,$fileName,$mimeType="application/octet-stream"){
if(!filesize($filePath)) return false;
$this->lstAttachs[$fileName] = array(
"Path" => $filePath,
"Mime" => $mimeType
);
return true;
}
function addRecipient($recName,$recMail,$recType){
if(!isset($recType)) $recType="to";
else $recType=strtolower($recType);
$recType=strtolower($recType);
if(!is_array($this->lstRecipients[$recType])){
$this->lstRecipients[$recType]=array();
}
$this->lstRecipients[$recType][$recMail]=$recName;
}
function addHeader($hdrName,$hdrValue){
$this->lstHeaders[$hdrName]=$hdrValue;
}
function setImportance($importance){
$this->addHeader("X-Importance",$importance);
}
function setSensitivity($sensitivity){
$this->addHeader("X-Sensitivity",$sensitivity,"X");
}
function setPriority($priority){
$this->addHeader("X-Priority",$priority);
}
function setAuth($authUser,$authPass){
$this->authUser = $authUser;
$this->authPass = $authPass;
}
function _debugLine($line,$sent=1){
$line=trim($line);
if(!$this->isDebug) return;
echo nl2br(htmlentities($line)."<br />");
}
function _sendLines($lstLines,$raw=0){
if($raw){
}
if(!is_array($lstLines)){
&;nbsp; $lstLines = str_replace("\r","",$lstLines);
$lstLines = explode("\n",$lstLines);
if(!count($lstLines)) $lstLines=array($lstLines);
}
foreach($lstLines as $line){
$line = trim($line);
$this->_debugLine($line);
if(!fputs($this->smtpSocket,$line."\r\n")){
return false;
}
}
return true;
}
function _getAnswer(){
$line="";
while(!feof($this->smtpSocket)){
$ch = fgetc($this->smtpSocket);
if(!strlen($ch)) return false;
if($ch=="\n"){
$this->_debugLine($line,0<;span class="phpoperator">);
&;nbsp;if($line[3]==" ") return (int)substr($line,0,3);
$line = ""; continue;
}
<;span class="phpkeyword">if($ch!="\r") $line.=$ch;
}
return false;
}
function _authLogin(){
$buf="AUTH LOGIN";
$this->_sendLines($buf);
if($this->_getAnswer()!=334){
fclose($this->smtpSocket);
return false;
}
$buf=sprintf("%s",base64_encode($this->authUser));
$this->_sendLines($buf);
if($this->_getAnswer()!=334){
fclose($this->smtpSocket);
return false;
}
$buf=sprintf("%s",base64_encode($this->authPass));
$this->_sendLines($buf);
if($this->_getAnswer()!=235){
fclose($this->smtpSocket);
return false;
}
return true;
}
function connect($timeout=5){
$errno = "";
$errstr = "";
$this->smtpSocket =
fsockopen ($this->smtpServer, $this->smtpPort,
$errno, $errstr, $timeout);
if (!$this->smtpSocket){
$this->_debugString($errno.":".$errstr."\r\n");
return false;
}
if($this->_getAnswer()!=220){
fclose($this->smtpSocket);
return false;
}
if(($this->authUser!="") && ($this->authPass!=""))
$buf=sprintf("EHLO %s","localhost");
else
$buf=sprintf("HELO %s","localhost");
$this->_sendLines($buf);
$hiReply = $this->_getAnswer();
if($hiReply == 250){
return $this->_authLogin();
}
$buf=sprintf("HELO %s","localhost");
if($this->_getAnswer()!=250){
fclose($this<;/span>->smtpSocket);
return false;
}
return true;
}
function disconnect(){
$this->_sendLines("QUIT");
$quitReply = $this->_getAnswer();
fclose($this->smtpSocket);
if($quitReply==221)
return true;
return true;
}
function _sendRecipients(){
$result = 0;
$mails = array();
$mailsErr = array();
while(list($type,$list)=each($this->lstRecipients)){
while(list($mail,$name)=each($list)){
if(in_array($mail,$mails)) continue;
$buf =sprintf("RCPT TO:<%s>",$mail);
$this->_sendLines($buf);
$rez =$this->_getAnswer();
array_push($mails,$mail);
if($rez==250) continue;
array_push($mailsErr,$mail);
unset($this->lstRecipients[$type][$mail]);
}
}
return ((count($mails)-count($mailsErr))>0);
}
function _sendHeaders(){
reset;($this->lstHeaders);
while(list($name,$value)=each($this->lstHeaders)){
$buf ="$name: $value";
$this->_sendLines($buf);
}
reset($this->lstRecipients);
while(list($type,$list)=each($this->lstRecipients)){
$mails = array();
while(list($mail,$name)=each($list)){
array_push($mails,"$name <$mail>");
}
$type[0] =strtoupper($type[0]);
if(isset($this->lstHeaders[$type])) continue;
$buf ="$type: ".implode(",",$mails)."";
$this->_sendLines($buf);
}
$buf=sprintf("From: %s <%s>",$this->fromName,$this->fromMail);
$this->_sendLines($buf);
if(strlen($this->replyMail)){
$buf=sprintf("Reply-to: %s <%s>",$this->replyName,$this->replyMail);
$this->_sendLines($buf);
}
$buf=sprintf("Subject: %s",$this->msgSubject);
$this->_sendLines($buf);
return true;
}
function _sendMessage(){
if($this->isMimeOn){
$buf =
"MIME-Version: 1.0\r\n".
"Content-type: multipart/mixed; boundary=\"#BOUNDARY#\"\r\n\r\n";
$this->_sendLines($buf);
$buf=
"\r\n--#BOUNDARY#\r\n".
"Content-Type: text/".($this->isHtml ? "html" : "plain")."; charset=us-ascii\r\n";
$this->_sendLines($buf);
}else{
$buf="\r\n";
$this->_sendLines($buf);
}
$this->_sendLines($this->msgBody,1);
return true;
}
function _sendAttachments(){
if(!$this->isMimeOn) return true;
if(!count($this->lstAttachs)) return true;
while(list($name,$file)=each($this->lstAttachs)){
$fpath = $file['Path'];
$mime = $file['Mime'];
$fname = $this->names[$i];
$newfile = fopen($fpath,"rb");
$content = fread($newfile, filesize($fpath));
fclose($newfile);
$content = base64_encode($content);
$buf =
sprintf("\r\n\r\n--#BOUNDARY#\r\n".
"Content-Type: ".$mime.";&;nbsp;name=%s\r\n".
"Content-Length: ".filesize($file)."\r\n".
"Content-Transfer-Encoding: base64\r\n".
"Content-Disposition: attachment; filename=%s\r\n".
"Content-ID: <%s>\r\n\r\n",
$name,$name,$name);
$this->_sendLines($buf);
$this->_sendLines($content,1);
}
return true;
}
function send($connect=false,$disconnect=false){
if($connect)
if(!$this->connect()) return false;
$buf=sprintf("MAIL FROM:<%s>",$this->fromMail);
$this->_sendLines($buf);
if($this->_getAnswer()!=250){ fclose($this->smtpSocket); return false; }
if(!$this->_sendRecipients()){ fclose($this->smtpSocket); return false; }
$this->_sendLines("DATA");
if($this->_getAnswer()!=354){ fclose($this->smtpSocket); return false; }
if(!$this->_sendHeaders()){ fclose($this->smtpSocket); return false; }
if(!$this->_sendMessage()){ fclose($this->smtpSocket); return false; }
if(!$this->_sendAttachments()){ fclose($this->smtpSocket); return false; }
$this->_sendLines(MSG_END);
if($this->_getAnswer()!=250){ fclose($this->smtpSocket); return false; }
if($disconnect){ $this->disconnect(); }
return true;
}
};
?>
As you have learned …
… I promptly reply to questions. So when you got them … shoot … in the Comment Form. I might have not explained this as well as I should have but do ask your questions!