I had the same problem. I have a development server at home and prod server at external server house and incoming mails go to other server. PHP:s mail()
works nicely in server house, but not at home.
I tested a bit and got it to work at home in the same manner as in server house. The difference between methods in server house and home is the configuration of sendmail. Server house I had only to install sendmail and it was fine, but at home I had to install also sendmail-cf and use it to add outgoing mail server address.
Let's assume you have Centos, Apache and PHP at home server and you want to send emails using PHP:s mail() function.
1) Set hostname on home server into two places: /etc/sysconfig/network and /proc/sys/kernel/hostname this way:
# nano /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=mydns157.dlinkddns.com
# nano /proc/sys/kernel/hostname
HOSTNAME=mydns157.dlinkddns.com
2) Install sendmail and sendmail-cf:
# yum install sendmail sendmail-cf
3) Add the following row into /etc/mail/sendmail.mc, where you have your ISP:s outgoing mail server:
define(`SMART_HOST',`mail.myisp.com')dnl
4) Update sendmail.cf:
# /etc/mail/make
5) Restart sendmail and apache:
# service sendmail restart
# service httpd restart
6) Boot to update hostname:
# reboot
That's it. Now the following works:
# php -r'mail("[email protected]", "Subject", "Body", null, "[email protected]");'
You can skip -f:
# php -r'mail("[email protected]", "Subject", "Body");'
in which case the sender's name become automatically user@hostname, eg. [email protected].
Some notes of hostname
The selection of hostname is critical. The default in Centos6 is localhost.localdomain
, but mail()
is not working with it if you skip your own sender address (eg. '[email protected]'
) when calling mail(). If you are sure, that you always call mail() using your real address as sender address, the hostname can be whatever, but if you have existing calls to mail() that lacks the sender address (I have hundreds of this like calls for testing purposes), then you must have a real domain as a hostname, because your server's hostname is used as a sender-address-domain in these cases. Real in the sense that domain must have at least DNS A-record (for some reason my ISP doesn't require NS-record for sender address, only A-record, but test and check with your ISP). The downside of using non-email-domain as a sender address is that replys and delivery notifications will go to bit's heaven, but if you drop sender address in your code, it usually means that you test and debug something and don't need reply functionality. The domain can be eg. the one you get from dynamic dns server eg. mydns157.dlinkddns.com
, which can point to your home router (but not have to). You can get DNS record in PHP using dns_get_record("mydns157.dlinkddns.com")
, which returns an array like this:
[host] => mydns157.dlinkddns.com
[type] => A
[ip] => 92.152.214.137
[class] => IN
[ttl] => 7
If type
in above DNS-record is NS
, then the domain acts as an email domain, which is OK for hostname of own server, but the effect is a little different. If you set as hostname an existing email domain eg. myexistingemaildomain.com
, and send a message to [email protected]
eg for debugging purposes, sendmail thinks that the message has to be delivered to mail-folder of user me
on this server. If me
user doesn't exist, the sending fails and if the user exists, then the message goes to /var/mail/me
. This can be what you want, but (like me) you may want that all messages are delivered outside instead of server folders.
Your hostname (in DNS record) doesn't need to point to your server's actual external IP to make mail() work in lack-of-sender-address cases, but there is no harm of it. The main thing is that hostname has a valid A-record and that the domain belongs to you. If the domain doesn't belong to you, then there may born a security hole. If you set as hostname some existing email domain eg. microsoft.com
(for whatever reason) and send a message to someone without adding your own sender address when calling mail() (eg. '[email protected]'
), the sender address will be automatically [email protected]
. If you are logged as root, the sender address will be [email protected]
. Replys and notifications of failed deliveries go then to [email protected]
and this may not be your intention.
yum install sendmail
should def help, cause if you havent installed it, chances are its not there in the system. – Nerti