How to send email from PHP without sending actual mail
Configure PHP to log emails to a file instead of delivering them to an SMTP server. This guide shows how to use the mail() function in debug mode on Ubuntu 24.04 with PHP 8.3.
Configure your PHP environment to log outgoing email messages to a file instead of attempting network delivery. This method is essential for testing email functionality during development without requiring a live mail server or risking messages going to the wrong inbox. The steps below apply to PHP 8.3.x running on Ubuntu 24.04.
Prerequisites
- Ubuntu 24.04 LTS or similar Debian-based Linux distribution
- PHP 8.3.x installed and configured via the system package manager
- Access to the server's configuration files (sudo privileges)
- A writable directory for the mail log (e.g., /var/log/php/)
Step 1: Locate the active PHP configuration file
Find the specific configuration file that PHP uses to load settings. On Ubuntu, this is often located in /etc/php/8.3/apache2/php.ini or /etc/php/8.3/cli/php.ini depending on your SAPI.
sudo find /etc/php/8.3 -name php.ini -type f
/etc/php/8.3/apache2/php.ini
/etc/php/8.3/cli/php.ini
/etc/php/8.3/fpm/php.ini
Identify which file corresponds to your environment (Apache, CLI, or FPM) and note the full path.
Step 2: Create a dedicated directory for mail logs
Create a new directory to store the email logs. This keeps your logs organized and prevents them from cluttering the root /var/log directory.
sudo mkdir -p /var/log/php/mail
Set the correct permissions so the PHP process can write to this directory.
sudo chown www-data:www-data /var/log/php/mail
sudo chmod 755 /var/log/php/mail
Step 3: Configure the mail log path in php.ini
Edit the active php.ini file found in Step 1. Locate the mail.log_path directive. If it does not exist, add it manually. This directive tells PHP where to write the email content and headers when debugging is enabled.
sudo nano /etc/php/8.3/fpm/php.ini
Add or modify the following line near the bottom of the file:
mail.log_path = /var/log/php/mail/php_mail.log
Save the file and exit the text editor.
Step 4: Enable mail debugging mode
Enable the mail_debug flag in the same php.ini file. This setting instruct PHP to log the email headers and body to the file specified in mail.log_path instead of sending the message.
mail_debug = 1
Ensure there are no spaces around the equals sign and that the value is exactly 1.
Step 5: Restart the PHP service
Apply the changes by restarting the relevant PHP service. If you are using PHP-FPM, restart the service using the systemd command.
sudo systemctl restart php8.3-fpm
If you are using Apache, restart the web server instead.
sudo systemctl restart apache2
Verify that the service restarted successfully without errors.
Verify the installation
Create a simple test script to confirm that emails are being logged. Create a file named test_mail.php in your web root.
sudo nano /var/www/html/test_mail.php
Paste the following code into the file:
Access the script via your browser or run it from the command line.
php /var/www/html/test_mail.php
Check the log file to see the output. You should see the email headers and body written to the file.
tail -f /var/log/php/mail/php_mail.log
You will see output similar to this:
*** Starting mail debug logging ***
To: recipient@example.com
Subject: Test Subject
From: sender@example.com
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
This is a test message sent without delivery.
*** Mail debug logging stopped ***
Troubleshooting
If the log file is empty or permissions are denied, check the following common issues.
Error: Permission denied when writing to log file
If you receive a "Permission denied" error when trying to write to the log file, the PHP process user does not have write access. Ensure the directory owner matches the PHP process user.
ls -ld /var/log/php/mail
If the owner is not www-data, change it:
sudo chown www-data:www-data /var/log/php/mail
Error: mail_debug flag ignored
If the mail_debug flag is set but emails are still being sent, the directive may be overridden by a .htaccess file or a different php.ini file. Ensure the flag is set in the correct php.ini file for your SAPI.
grep mail_debug /etc/php/8.3/fpm/php.ini
Verify the value is 1. If the directive is missing, add it manually.
Error: Log file not created
If the log file does not exist after running the test script, ensure the directory exists and has the correct permissions.
ls -l /var/log/php/mail
Create the file manually if it does not exist:
sudo touch /var/log/php/mail/php_mail.log
Ensure the file is writable by the www-data user:
sudo chown www-data:www-data /var/log/php/mail/php_mail.log
Restart the PHP service again to apply any changes.
Error: mail() function returns false
If the mail() function returns false, the mail_debug flag may not be taking effect. Check the error log for additional details.
sudo tail -n 50 /var/log/syslog | grep php
Ensure that the mail.log_path directive is set correctly and that the path is accessible.
Clearing old log files
To rotate or clear old log files, use the truncate command or remove and recreate the file.
sudo truncate -s 0 /var/log/php/mail/php_mail.log
This clears the file without deleting the directory or losing permissions.