Email

PHP mail(): what the result means and when to use SMTP

Reviewed on 4 min read php smtp

PHP's mail() function

PHP lets you hand a message to the local mail transport using mail(). Always set a valid sender that the application controls:

$headers = ['From' => 'web@tudominio.com'];
$accepted = mail('email@destino.com', 'Título email', 'Mensaje', $headers);

A true result only confirms that the local system accepted the message for processing; it does not prove that the recipient's server accepted it or that it reached the inbox.

Problems caused by using mail()

The weak point of a message that is hard to diagnose is the lack of information about what happens after it is handed to the transport. Before replacing code, check whether the message was accepted, rejected or left pending.

The function lets you build the sender header without itself authenticating that the application controls that domain. Never accept a From value freely supplied by the visitor; use a fixed address on your domain and put the user's address in Reply-To only after validating it.

Providers check mechanisms such as SPF, DKIM and DMARC, as well as the message's reputation and format. mail() does not set up those mechanisms on its own or report the final delivery result.

An incomplete setup can lead to rejections or spam classification, but the result must be checked in delivery tracking and in the headers of a real message.

Whether mail() is suitable does not depend on whether the recipient is your own or external, but on how the local transport is configured, the resulting authentication and your ability to see errors and bounces. For important messages, use a transport that lets you authenticate, log the result and control the sender.

Emails sent with SMTP authentication

An alternative is sending through authenticated SMTP with a real account created in cPanel. Use the hostname with a valid certificate shown in Connect Devices, mandatory TLS and the recommended secure port. The From must be an address you control, aligned with the authenticated account or domain. SMTP improves control and traceability, but it does not guarantee that the receiver will accept the message either.

Do not change the sender to a Gmail account as a general fix. Gmail can be used through its SMTP or OAuth settings when the application supports it, but a 401 error relates to that authorisation and must be solved separately; it does not diagnose the local mail() transport or delivery to the recipient.

Many applications include an option to set up SMTP. In Joomla you can select that transport and enter the account's server, encryption and credentials. Check the result with a real message sent from the application.

In WordPress you can use a compatible SMTP plugin, such as Easy WP SMTP.

For custom developments, you can integrate a maintained library such as PHPMailer

Prepare the switch to SMTP

Store the credentials in the application's private configuration, outside the repository and the public directory. Use a maintained library, certificate validation and the port and TLS mode given by the provider. Do not turn off certificate verification to hide a connection error.

Send a representative test and log the date, recipient and message identifier without storing passwords. Check delivery tracking and the result at the receiver. If your application retries, avoid creating duplicates when the first message was already accepted but the response was lost.

Do not put unvalidated form data into recipients or headers. To reply to the visitor, validate their address and use it as Reply-To, keeping a From that your application controls.

You may also find useful

Something wrong or out of date? Tell us and we will review it.