Are there any SMTP alternatives to mail()?

Being on a shared hosted server, I cannot install anything but I’m looking for an alternative to the insecure mail() function that is built-in to PHP. I do have SMTP server access and found and slightly modified some code written by others but not sure what to do with it. While I can see what it does in general, how does it actually send a message through fwrite() alone or does it simply generate better, more secure headers?

Also, any idea what $B = 8192; is for?

(Message() is my own custom function that simply presents a message on-screen and has nothing to do with the functionality.)

// FOR TESTING PURPOSES ONLY
function smtpmail($to, $subject, $body, $headers) {
	$smtp = stream_socket_client('tcp://mail.someserver.com:25', $eno, $estr, 30);

	if (!$smtp) :
		Message("$estr ($eno)<br />\n");
	endif;

	$B = 8192;
	$c = "\r\n";
	$s = '[email protected]';

	fwrite($smtp, 'helo ' . $_ENV['HOSTNAME'] . $c);
	$junk = fgets($smtp, $B);

	 // ENVELOPE
	fwrite($smtp, 'mail from: ' . $s . $c);
	$junk = fgets($smtp, $B);
	fwrite($smtp, 'rcpt to: ' . $to . $c);
	$junk = fgets($smtp, $B);
	fwrite($smtp, 'data' . $c);
	$junk = fgets($smtp, $B);

	// HEADER 
	fwrite($smtp, 'To: ' . $to . $c); 
	if(strlen($subject)) fwrite($smtp, 'Subject: ' . $subject . $c); 
	if(strlen($headers)) fwrite($smtp, $headers); // Must be \r\n (delimited)
	fwrite($smtp, $headers . $c); 

	// BODY
	if(strlen($body)) fwrite($smtp, $body . $c); 
	fwrite($smtp, $c . '.' . $c);
	$junk = fgets($smtp, $B);

	// CLOSE
	fwrite($smtp, 'quit' . $c);
	$junk = fgets($smtp, $B);
	fclose($smtp);
}

This one indeed is just sending raw data to the SMTP server via fwrite.

So the person who wrote this has created the handshake followed by the exchange of data by sending messages and receiving and analysing the replies

However, this isn’t a new problem and thus there are quite some way more convenient libraries available.

One popular implementation is PHPMailer where you can just drop in your server data and credentials in a config and use the class methods afterwards.

It is quite powerful, rock solid and battle tested for several years

You can put php scripts, such as phpmailer or swiftmailer onto the server, the same as you can put your own php scripts.

The mail() function is not insecure or secure in itself. If you feed it body data that contains spam’ie content or contains non-escaped javascript or headers which tell it to send to any email address that was submitted to your code, it will use that data and headers. The script you have here is just as insecure or as secure as the mail() function.

What? You would call it in place of the mail() function.

It is opening a tcp/ip connection to the mail server. The fwrite() statements are sending smtp commands, that a mail server understands, that cause it to receive and queue the email to be sent to the receiving mail server.

That’s the maximum length parameter to the fgets() call, that’s reading back the response from the mail server to each line you send it.

Two specific points about the posted code -

  1. A connection error is a fatal problem. The code should return at that point to stop execution.
  2. By reading and discarding the responses sent back by the mail server, any errors are not being handled. You should detect and log any errors and if one occurs, setup and output a general error message to the user.

Short-version: you can put php scripts, such as phpmailer or swiftmailer, onto your hosting, rudimentary code that sends smtp commends directly to the mail server, but doesn’t contain useful error handling, is not an improvement, and is just as insecure or secure as the mail() function.

Thank you. I had guessed as much about what it did - and it was a guess - but working with an SMTP server directly (other than in a desktop mail client) is not something I had ever done so I wasn’t sure.

I do understand that mail() itself is not actually insecure but from various topics online it was suggested that it typically does not provide certain headers that minimize it being blocked my spam filters.

One thing on the function I posted, though, is that I see no provision for a password that my SMTP server requires.

Thank you. I had considered PHPMailer but until now I was under the impression that it required some installation on the server. After I posted, my hosting company also suggested it so I will look into whatever is needed to implement it.

The problem with the mail function in shared hosting is mostly about the DNS for that server not being properly set up to support mailing (SPF, DKIM) as well as all of the other users would be sending from the same IP as you do.

So even when you are a good guy, if any of the other customers on the same shared hosting goes mad about mailing, the reputation of the whole IP is getting damaged along with the reputation of you domain. This is really hard to recover from afterwards.

So indeed it is a good idea to send mail through a property configured and set up mailserver.

If this however is one shared one of a small host who isn’t a member of the alliance (forgot full name of that alliance) you may be facing similar issues when you share the box with a spammer.

Ideally you have a trusted big email provider or you are running your own smtp.

Either way, any smtp server is still better than mail() in terms of reputation.

There are Extended SMTP (ESMTP) commands and responses used for authentication.

I actually have a dedicated IP but I’m not sure if it applies to the SMTP server.

How would this authentication be applied to the function?

This as well works by sending special messages to the smtp server.

I won’t go into an in depth discussion about a specific protocol implementation here, specially because it’s not a php topic as well as there are libraries out there to be used.

If you are interested in the underlying communication, you may wanna take a look at RFC 4954

Sponsor our Newsletter | Privacy Policy | Terms of Service