How to send e-mail using PHP and mail() with Linux Debian


Note: This is tested and proven to work on Debian Squeeze (stable)

If you are a web-admin or a PHP developer hosting on your own servers you might have found out that PHP mail() function does not work out of the box in Debian unless you have installed Exim (default MTA for Debian Squeeze), sendmail or some other MTA. Most of the time this is OK, but when you really don't want to mix a mailserver with your webserver this is going to be a problem.

In php.ini file there is a SMTP configuration value that you can set which is misleading. Even though you set the SMTP value, PHP mail() function will not connect directly to the SMTP server and relay emails rather it depends heavily on sendmail program which can be set via the sendmail_path configuration value. In conclusion you'll have to have a working sendmail program if you want to use PHP mail() function.

So rather than using a complete MTA just to relay emails to your mailserver you can use SSMTP which is a send-only sendmail alternative.


From SSMTP man page
ssmtp is a send-only sendmail emulator for machines which normally pick their mail up from a centralized mailhub (via pop, imap, nfs mounts or other means). It provides the functionality required for humans and programs to send mail via the standard or /usr/bin/mail user agents.
1. Installation
# aptitude install ssmtp
 
2. Configuration
SSMTP has two configuration files;
  • /etc/ssmtp/ssmtp.conf - configuration file
  • /etc/ssmtp/revaliases - reverse aliases file
/etc/ssmtp/ssmtp.conf
#
# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
root=webmaster@domain
This is used to send all emails sent by system users as from the above email address so they can be replied to. e.g. If you are using mod-php then all mail will be sent out as www-data@web.server, you can change this to webmaster@domain by setting the above configuration value.
# The place where the mail goes. The actual machine name is required no
# MX records are consulted. Commonly mailhosts are named mail.domain.com
# Use mail.domain.com:PORT if you want to specify PORT (e.g. mail.server:587)
mailhub=mail.server
This is your actual mail server which acts as the MTA.
# The full hostname
hostname=web.server
This is the webserver name. You can leave this blank to force ssmtp to detect hostname.
# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
FromLineOverride=YES
Very important, if you set this to NO (which seems to be the default) all your messages will be sent out as www-data@web.server and cannot be overridden by "From: " fields.
Note: www-data is the user executing the PHP mail() function which is usually the apache daemon user unless you are using suExec.
If your SMTP server requires authentication and/or TLS, you'll have to set the following configuration settings.
AuthUser=youremail@mail.server
AuthPass=yourpassword
UseSTARTTLS=yes
UseTLS=yes
/etc/ssmtp/revaliases
# sSMTP aliases
#
# Format:       local_account:outgoing_address:mailhub
#
# Example: root:your_login@your.domain:mailhub.your.domain[:port]
# where [:port] is an optional port number that defaults to 25.
#
www-data:webmaster@example.com
This file is used to configure Reverse Alases and only works when a email "From: " field is not specified or FromLineOverride=NO


If you want to use Google mail servers add the following configuration value to /etc/ssmtp/ssmtp.conf
AuthMethod=LOGIN

3. Testing
------------- mail.txt ---------------- To: someone@example.com
From: "Do NOT Reply"
Subject: Testing SSMTP
This is a test message sent from SSMTP.
If you remove the "From:" field from your message SSMTP will map the *nix username to an email address (username@host). You can change the mapping using the /etc/ssmtp/revaliases file as above.
$ /usr/sbin/ssmtp -t < mail.txt
 
Note: At this point ssmtp is configured properly and PHP mail() function should also be working. To make it more precise we can change the PHP sendmail_path to /usr/sbin/ssmtp -t
sendmail_path = /usr/sbin/ssmtp -t

4. Test PHP
<?php
$to
= '"Somename Lastname" <someone@email.com>';$subject = 'PHP mail tester';$message = 'This message was sent via PHP!' . PHP_EOL .
          
'Some other message text.' . PHP_EOL . PHP_EOL .
          
'-- signature' . PHP_EOL;$headers = 'From: "From Name" <from@email.dom>' . PHP_EOL .
          
'Reply-To: reply@email.com' . PHP_EOL .
          
'Cc: "CC Name" <cc@email.dom>' . PHP_EOL .
          
'X-Mailer: PHP/' . phpversion();
          
if (
mail($to, $subject, $message, $headers)) {
  echo
'mail() Success!';
}
else {
  echo
'mail() Failed!';
}
?>