How to send emails with the PHP mail() function

The PHP mail() function is a built-in way to send emails directly from a PHP script.
Developers often use it for simple tasks like sending contact form messages or testing email functionality.
While it is easy to use, the mail() function has limitations that make it better suited for learning and small projects than for production environments.
What is the PHP mail() function?
The PHP mail() function lets your website send emails without needing an external library. It works by calling the web server’s mail transfer agent (MTA) to deliver messages.;
The function takes in at least three parameters: the recipient’s email, the subject line, and the message body. You can also include optional headers like From, Reply-To, and content type.
This makes mail() one of the quickest ways to test sending emails in PHP. However, it doesn’t offer modern features like authentication, attachments, or reliable spam protection.
PHPMailer vs mail() function: pros and cons
While mail() is simple, it lacks flexibility. PHPMailer, on the other hand, is a popular library that provides advanced email features like SMTP support, authentication, attachments, and HTML formatting.
Pros of mail():
- Built into PHP
- Easy to use
- No installation required
Cons of mail():
- Limited functionality
- Higher chance of being flagged as spam
- Harder to debug errors
If you need advanced features, consider using PHPMailer. We’ve covered it in detail in our guide on how to send emails using PHPMailer.
How to send emails using the PHP mail() function
Here’s the basic syntax of the mail() function:
mail(to, subject, message, headers, parameters);
- to – the recipient’s email address.
- subject – the email subject line.
- message – the body of the email.
- headers – additional information like From, Reply-To, or Content-Type.
- parameters – optional extra options passed to the system’s sendmail program.
Understanding PHP mail components
To send an email successfully, you need to set up correct headers:
<?php $to = "example@domain.com"; $subject = "Test email from PHP"; $message = "This is a plain text email example."; $headers = "From: hello@domain.com" . "\r\n" . "Reply-To: hello@domain.com" . "\r\n" . "X-Mailer: PHP/" . phpversion(); mail($to, $subject, $message, $headers); ?>
- From – sets the sender address.
- Reply-To – defines where replies should be directed.
- X-Mailer – identifies that the message was sent by PHP.
Creating a test file for PHP mail
To test mail(), create a testmail.php file in your server root:
<?php $to = "youraddress@example.com"; $subject = "PHP Mail Test"; $message = "This is a test message sent from PHP."; $headers = "From: webmaster@yourdomain.com"; if (mail($to, $subject, $message, $headers)) { echo "Email sent successfully."; } else { echo "Email delivery failed."; } ?>
Upload this file and access it in your browser. If configured correctly, you should receive an email.
Sending HTML emails with PHP
By default, mail() sends plain-text emails. To send HTML emails, add a Content-Type header:
<?php $to = "example@domain.com"; $subject = "HTML Email Example"; $message = " <html> <head> <title>HTML Email</title> </head> <body> <h1>Hello!</h1> <p>This is an <strong>HTML</strong> email sent with PHP.</p> </body> </html> "; $headers = "MIME-Version: 1.0" . "\r\n"; $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n"; $headers .= "From: hello@domain.com" . "\r\n"; mail($to, $subject, $message, $headers); ?>
This allows you to format text, add headings, and style your message with HTML.
How can I validate email addresses before using the PHP mail() function or PHPMailer to send emails?
Validating email addresses helps prevent errors and reduce spam issues. PHP provides filter_var() for this:
<?php $email = "user@example.com"; if (filter_var($email, FILTER_VALIDATE_EMAIL)) { echo "Valid email address."; } else { echo "Invalid email address."; } ?>
This ensures you only send emails to properly formatted addresses.
How to troubleshoot common PHP mail() function errors
The mail() function can fail for several reasons. Here are the most common issues:
- Mail goes to the spam folder
- Could not connect to SMTP host
- Gmail couldn’t verify that domain.tld sent this message
- Sender address rejected: not owned by the user
- Mail not delivered at all (silently failing)
- Incorrect headers or formatting
Mail goes to the spam folder
Emails often end up in spam if headers are incomplete or if the content looks suspicious. To reduce the risk:
- Use a proper From address matching your domain.
- Avoid trigger words that spam filters flag.
- Set up DNS records like SPF and DKIM for domain verification.
Example of adding From and Reply-To headers:
$headers = "From: no-reply@yourdomain.com\r\n"; $headers .= "Reply-To: support@yourdomain.com\r\n"; $headers .= "X-Mailer: PHP/" . phpversion();
Could not connect to SMTP host
This error indicates a server configuration problem. Possible causes include:
- The hosting provider blocks outbound mail.
- PHP mail is disabled in php.ini.
- Firewall rules are preventing the connection.
Example of checking mail function in php.ini
; Make sure this is not disabled disable_functions =
Gmail couldn’t verify that domain.tld sent this message
Gmail and other providers require domain authentication to trust your messages. To fix this, ensure you have the following TXT entries in your DNS records:
- Add an SPF record to specify authorized mail servers.
- Enable DKIM to verify message integrity.
- Set up DMARC to protect against spoofing.
Example of an SPF record:
v=spf1 include:_spf.[domain.tld] ~all
Example of a DKIM record:
Name: [selector]._domainkey.[domain.tld] Content: v=DKIM1; p=[series of numbers]
Example of a DMARC record:
Name: _dmarc.[domain.tld] Content: v=DMARC1; p=none; rua=mailto:[yourname]@[domain.tld]
Sender address rejected: not owned by the user
This happens when the sender email does not belong to your domain. To resolve it:
- Always use a valid sender address, like no-reply@yourdomain.com.
- Avoid using third-party addresses such as Gmail or Yahoo in the From field.
Example of a correct sender address:
$headers = "From: no-reply@yourdomain.com\r\n";
Mail not delivered at all (silently failing)
Sometimes the mail() function does not throw an error but messages never arrive. Common reasons include:
- The hosting provider blocks PHP mail for security reasons.
- The server is misconfigured.
- Logs show messages being dropped.
Example of logging mail() results in PHP
if (mail($to, $subject, $message, $headers)) { error_log("Mail sent successfully to $to"); } else { error_log("Mail failed to send to $to"); }
Incorrect headers or formatting
Improper headers cause delivery failures or corrupted emails. Follow these practices:
- Always use \r\n for line breaks in headers.
- Include MIME-Version and Content-Type when sending HTML emails.
- Keep formatting consistent to avoid parsing errors.
Example of correct HTML headers:
$headers = "MIME-Version: 1.0\r\n"; $headers .= "Content-type: text/html; charset=UTF-8\r\n";
When to move beyond the mail() function
The PHP mail() function is useful for learning, debugging, and sending simple test messages. However, it is not the best choice for production use. If you need reliable delivery, attachments, or SMTP authentication, move to a more powerful library like PHPMailer or connect to an external email service.
All of the tutorial content on this website is subject to Hostinger's rigorous editorial standards and values.
Comments
June 13 2017
Cool article, But I have a problem with this part: 'smtp', 'host' => 'smtp.mailgun.org', 'port' => 587, 'from' => array('address' => 'something@gmail.com', 'name' => 'You name here'), // Place things in '' ( quote ) here 'encryption' => 'tls', 'username' => 'yourUsername', // Place things in '' ( quote ) here 'password' => 'yourPassword', // Place things in '' ( quote ) here 'sendmail' => '/usr/sbin/sendmail -bs', 'pretend' => false,
June 14 2017
Hey, Can you elaborate?
June 15 2017
Hey, Can you provide more details? Do you get any errors?
June 18 2017
Thank you..it helped a lot......
February 23 2018
What is the SMTP Port number for Non-Secure?
February 27 2018
Hello, Niroj. To keep security up to date, Hostinger only allows sending mail through secure ports. Therefore, non-secure SMTP is not supported.
October 05 2018
I actually have a question. The problem is my browser is displaying what appears to be a dialog of the SERVER/CLIENT for each step of the behind the scene processing just before the "Message sent!" message. I just want the "Message sent!" to appear. also i set $mail->SMTPDebug = 2;
October 08 2018
Hello, Prasey. To disable the server-side message, you'd have to set your SMTPDebug value to 0. That way, you will only see a "Message sent!" message without any additional log information.
March 01 2019
Thanks Buddy, Worked great !
March 18 2019
Wow, thank you very much for the tutorials, they are very helpful.
May 10 2020
Thank You !!! Useful
June 08 2020
Just adding that, for people without SSH access and unable to install composer, they can still use PhpMailer. Please refer the below link https://stackoverflow.com/questions/48128618/how-to-use-phpmailer-without-composer
July 04 2020
I have been trying to test this code and realized that whenever I add the following lines I get error 500 use PHPMailer\PHPMailer\PHPMailer; require 'vendor/autoload.php'; Is this outdated?
July 07 2020
Hey there Jorge! :) To use that script you will need composer to be installed and enabled first. Please follow the guide here. If you still struggle with it, you can always message our support team! I am sure they will be happy to help! :)
August 09 2020
Whenever I put my ssh username and password the ssh command prompt automatically disappear .. how can i fix this
November 06 2020
Hey Suman. Make sure you are manually writing the SSH password. If you copy-paste it, it may not accept it and give you an empty response.
August 23 2020
Thank You, but the only thing is that I noticed that the mail was sent without and Avatar/Organization Picture and I don't know I can add that. Any Suggestion
November 06 2020
Hey there Joao. You can check this little thread here on how you can approach the task at hand.
September 09 2020
I have purchased domin and hosting but i didn't get it free 1 emailer so please tell....
November 11 2020
Hey Akshay! :) You can check here how to create your email in your new plan!
September 30 2020
for laravel smtp mail this works MAIL_DRIVER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_USERNAME=***@gmail.com MAIL_PASSWORD=****** MAIL_ENCRYPTION=tls but this is not working for me MAIL_DRIVER=smtp MAIL_HOST=smtp.hostinger.in MAIL_PORT=587 MAIL_USERNAME=mail@mywebsite.com MAIL_PASSWORD=********* MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS=mail@mywebsite.com MAIL_FROM_NAME="mail@mywebsite.com" error message "Expected response code 354 but got code "554", with message "554 5.5.1 Error: no valid recipients ↵" Any suggestion ????
November 18 2020
Hey there Sujith. Please drop a line to our Customer Success and we will help you out with it! :)
October 05 2020
hey I tested your PHP mail but it doesnt send an email though it confirms it was sent successfully. Can you please help me?
November 18 2020
Hey Joel. If you are sending something like "test" or "hey" email, it may get caught by the spam filter. Please try sending a normal email as test. If you still have an issue afterwards, just drop a line to our Customer Success team.
November 29 2020
Hey i tried this method to send a mail by making a request from a javascript page and the $_POST seems to be always empty. If i set everything as queryparams and do a get request it works but I want to do a post request and add the info in the body.
February 09 2021
Hi there! Did you receive any error messages with error display enabled or found anything in your error_log? If you won't be able to resolve it on your own, don't hesitate to contact our Customer Success team to help you troubleshoot!
November 30 2020
require(vendor/autoload.php): failed to open stream: No such file or directory
February 09 2021
Hi there! If you're getting this error, the chances are your composer isn't working correctly. Refer to article over here on how to install it ;)
December 23 2020
This page isn’t working mywebsite.com is currently unable to handle this request. HTTP ERROR 500
February 09 2021
Hi there! You'll find how to overcome error 500 over here - it will help you understand which line of code is an error and fix it :)
September 07 2021
I am trying to send mails through PHP Mail component through contact form of website. But HTTP Error 500 responds every time. Is web server not suitable for PHP Mail service ?
September 20 2021
Hi there, HTTP 500 error suggests that there's likely an issue with the code of the file you're trying to execute. I'd suggest to look through your code again with a PHP error log or error display :)
September 29 2021
Hi there! I have tested sending mails by following your phpmailer tutorial and it worked. Great tutorial. Thanks!
September 29 2021
Happy it worked out!
October 04 2021
Sending the testmail through my browser doesn't work. When I type mydomain.com/testmai.php in a chrome address bar.l It takes me to the website 404 page not found.
October 05 2021
Hi Terry, please make sure to double-check your URL - it looks like you might be missing an L at the end of your URL - mydomain.com/testmail.php If anything, double-check the directory in which you placed your testmail file and ensure it's correct. Good luck!
January 15 2022
My site php mail() function is not working, please what should I do?
January 18 2022
Hi Eddy, first thing I would check what error you're receiving when you try to run it. If it suggests a code error, I would check to make sure the code and values inside of your phpmailer file are correct. If it says that the email is sent, but you don't receive it, there might be an issue with your sendmail service, emails going to spam, lack of SPF or DKIM records. If that's case, I'd suggest to check with your host :)
March 19 2022
Nice tutorial. Please how do I go about creating and auto welcome email for anyone who registers in my website
March 22 2022
Hi there :) It would depend on what CMS/framework you're using for your website, but generally, what you're looking for is the script, which registers new users to include a trigger to send a PHP mail. Then simply create the PHP mail file with your desired content! Let me know how it goes for you :)
April 23 2022
if i were to use an SMTP Relay service (e.g., Mail Jet, SendGrid, MailGun) other than hostinger.com's SMPT. how would i go about updating the DNS mx record to work with those SMTP Relay services?
April 25 2022
Hi William! You'd need to (1) get the required MX and other necessary DNS records from the new service provider; then (2) change them on your Hostinger DNS zone like this. If you run into any issues, feel free to check in with our Customer Success team!
June 02 2022
thank you, it helpful
June 03 2022
Hi, please am trying to access my test.php file from an external html using ajax, but it's not working, used allow access origin in htaccess but still no good news
June 07 2022
Hi there! I'd suggest to start by looking at the permissions of your test.php file - it could be that they're not set well for what you're intending to do ?
July 08 2022
HI. Very useful tutorial - tx. I have a strange problem using PHPMailer 6.6.3 (also had it with 6.0.7). I can sent emails to addresses in my own domain and they are delivered ok. But any address not in my domain causes a PHPMailer instantiation failure - error message is 'Could not instantiate mail function.' It is perhaps worth adding that before I recently moved to Hostinger for hosting services, I never had this problem. Appreciate if you can shed any light on this. Tx
July 14 2022
Hey there. Chris! To help you further with this issue, please contact our Customer Success team from your account, as the issue would require a bit more information, but no worries! The team will be there to assist you further! ?
August 09 2022
Hello i used simple mail function to send otp but there is limit after 100 mail no mail sent .. How to resolve it
August 12 2022
Hey there! With the Sendmail function, you're able to send 60 emails per minute using PHP. If the limit is exceeded, the email service gets temporarily suspended. If you wish to send more emails, we would suggest using PHP Mailer. This way you would be able to send 200 emails per user / 500 per IP per hour using SMTP ?
December 11 2022
Can’t send emails telling me unable to authenticate I’ve changed passwords couple of times Still same error
December 15 2022
Hey! Please double-check your email configuration details for the PHP Mailer before trying to send emails, you can refer to this article to learn how to find them. If any issue persists, please contact our Customer Success team.
January 23 2023
I already used the free email to my web app. My question is, how many emails or what is the maximum number(if have) of emails that I can send everyday? My plan is Cloud startup Plan. Thank you for reply
January 26 2023
Hey there! With the free email services you can send up to 500 emails every 24 hours. You can check this article to learn how to check the limits for your email services.
March 04 2023
Thanks for the great job. My PHPMailer is sending email but keeps using the same subject for different OTP email notification even though they go with different subjects. That is, when the email is sent, the subject stays the same but when you toggle to see sender information, you'll get to see the actual subject inside. Help please
March 10 2023
Hello there! It seems there is an issue with your PHPMailer code, specifically the parts that are responsible for subject. I have found a similar issue raised in Github. However a correct troubleshooting requires your code, thus I would suggest to consult with PHPMailer developers on Github, I'm sure they will help you out!
March 09 2023
can i save the mail to the sent box then retrive it by imap ??
March 10 2023
Hey there! Yes, it's possible to sync different email accounts with tools like IMAP sync. All you will need to do is fill in both email accounts names, passwords and IMAP server hostname.
March 17 2023
Hello! Make sure that the sender is using isHTML() method properly, it must be specified after Body. More information can be found in this post.
April 04 2023
Hi, The contact form can send messages, but they can't be received at my email address. Please note: 1) the PHP mailer is already installed. 2) I have created and installed the formscript in the public_html folder. I tested the formscript with the browser, and it works fine. Messages can be sent from the formscript and be received at my email address. 3) I have read and followed the guidelines of Hostinger's article/tutorial: "Using PHPMailer with Hostinger SMTP." Still, the contact form on my website sends messages, but they can't be received at my email address.
April 07 2023
Hello there! Here's a couple suggestions what you could do: 1. Make sure that formscript.php file is updated to match with your existing email account details. Pay extra attention to the
$mail->addAddress('recipient@domain.tld', 'Receiver Name');
line as that needs to be changed. 2. Check the SPAM folder on the receiving inbox, the email could be there. 3. Try the script with different recipients and see if the email gets delivered. 4. Try out the simplified version of the mailer script called phpmailer.php, you can find the details about it in the same tutorial.June 06 2023
this is my .env file MAIL_MAILER=smtp MAIL_HOST=smtp.hostinger.com MAIL_PORT=465 MAIL_USERNAME=*email from email hostinger* MAIL_PASSWORD=my pasword MAIL_ENCRYPTION=ssl I have made sure to use a valid destination email, but when i send email with laravel mail, always error like this: Swift_TransportException Expected response code 354 but got code "554", with message "554 5.5.1 Error: no valid recipients " Any suggestion?
June 08 2023
Hello, try adding this code to your .env file: MAIL_FROM_ADDRESS=you@email.com MAIL_FROM_NAME="you@email.com"
August 06 2023
i keep getting the error: Fatal error : Uncaught Error: Attempt to assign property "SMTPDebug" on null
August 11 2023
Hello there! Make sure you are using exactly same code as in tutorial to test out if everything works properly. Also make sure that PHPMailer is installed.
October 15 2023
This might mean that the object you created is null, likely indicating an issue with the creation or initialization of the PHPMailer instance.
August 25 2023
Hi, I met a problem with sending emails via SMTP. I'm using symfony mailer component and when I try to send an email, I've got this error: "Connection could not be established with host "smtp.hostinger.com:587": stream_socket_client(): php_network_getaddresses: getaddrinfo for smtp.hostinger.com failed: Temporary failure in name resolution" What can be the reason?
August 25 2023
Hello there! Seems like the script is not able to resolve hostname, I would suggest trying using an IP address instead of smtp.hostinger.com which is 172.65.255.143. Also check this Stackoverflow post as it's talking about similar issue.
October 18 2023
how can we save the email after sending it from PHPMailer?
November 03 2023
Hi there! Thanks for the question. To save emails sent via PHPMailer, you can configure your email server or email client to automatically save copies of outgoing messages. This is a convenient and hassle-free way to ensure that you have a record of all your emails, even if they are lost or accidentally deleted. I hope this helps! ?
June 26 2024
Hi, I have your Cloud Startup package. Is PHPMailer already pre installed or o i have to install it?
June 27 2024
Hi Simon! PHPMailer is not pre-installed on Hostinger Cloud Hosting. However, PHP is fully supported on all our hosting plans, including Cloud Hosting. You can manually install PHPMailer or use Composer to manage its installation according to your needs :)
July 26 2024
How to speed up sending email prosess for bulk email
July 31 2024
Hi there! To speed up the process of sending bulk emails, consider these tips: Use a reputable email marketing service, ensure your email list is clean and verified, and avoid using too many images or large attachments. Also, try sending emails during off-peak hours to reduce server load. These steps can help your emails reach recipients faster ;)
August 27 2024
Hey, is it possible for Hostinger to store my Gmail app password as a secret using a variable? If yes. How can I do this?
August 28 2024
Hi! To securely store passwords, it's recommended to use password managers or the secure storage options available through your operating system or third-party services ;)