How to use HELO with PHP’s mail() function

I originally wrote this for the HELO-community tracker, and it was subsequently published on BeyondCode’s blog, but I wanted to publish it here as well.


HELO works very nicely if you’re sending via SMTP using PHPMailer, SwiftMailer, etc. – but lots of apps and scripts rely on PHP’s clunky old mail() function, which isn’t nearly as easy to deal with, and harder to point at HELO.

You can configure “proper” mail servers like postfix to work as a local relay, but it’s horribly complicated and confusing to set up. Fortunately there are simpler alternatives that are much easier. Searching for local relay tools (what this is) will usually point you at ssmtp, however, that doesn’t work on macOS. A better option for macOS is msmtp which is present in homebrew and works perfectly. I usually run HELO on localhost port 2500, and I configure msmtp with a config file (stored in ~/.msmtprc; you should also chmod 600 this file as it may contain secrets) like this, which enables the authentication that HELO requires, and I’ve also enabled logging so you can see what it’s up to:

defaults
host localhost
port 2500
tls off
undisclosed_recipients off
account default
auth plain
user test
password password
logfile ~/logs/msmtp.log
syslog offCode language: Bash (bash)

To make the PHP mail function use msmtp, you need to configure the sendmail_path setting in your php.ini file to point at it:

sendmail_path = /usr/local/bin/msmtp -t -iCode language: Bash (bash)

If you’re using homebrew’s PHP package on macOS, I recommend putting config changes like this in a separate .ini file so that it remains update-safe; I put mine in /usr/local/etc/php/8.0/conf.d/marcus.ini.

With those two things in place, PHP’s mail function will submit to the local msmtp binary, which will then relay the message to HELO over SMTP.


Sending via this this route using PHPMailer is very simple because mail() is the default mailer, so you don’t need to configure anything:

<?php

use PHPMailer\PHPMailer\PHPMailer;
require 'vendor/autoload.php';

$mail = new PHPMailer();
$mail->setFrom('from@example.com', 'First Last');
$mail->addAddress('whoto@example.com', 'John Doe');
$mail->Subject = 'Say Hello to HELO';
$mail->Body = '<h1>Hi!</h1><p>This is my HTML body</p>'
$mail->AltBody = 'This is a plain-text message body';

if (!$mail->send()) {
    echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
    echo 'Message sent!';
}Code language: PHP (php)