Как исправить php mail error

Php mail functionsAre you having trouble understanding PHP mail functions and experiencing PHP mail not working? Have you recently swedged to understand how PHP mail works? You’ve come to the right place, as we have demystified most possible problems you could face with non working PHP mail.

Are you a PHP professional, or perhaps a novice who has yet to master the ropes? Irrespective of the circumstance, there is still more to know about any programming language, and there are occasionally materials that will help developers get better. This is one of them!

Our skilled team has gone above and beyond to explain the concept in this topic to assist you in understanding the scope and concept of how PHP mail works, error handling within a PHP mail function, setting it up to work, and sending PHP mail through Gmail. Here we begin our quest to become a better PHP developer.

Your task now is to give it your all and absorb the information you’ve been given.

Contents

  • Why Is PHP Mail Not Working?
  • Steps in PHP Mail Test
  • PHP Mail Error Handling – The Right Way
  • Conclusion

The PHP mail() function allows users to send emails to users by using a script. This function takes three necessary input arguments that define the recipient’s email address, its subject, and the message to be sent as well as two optional parameters which are the headers and parameters.

Moving on with the PHP mail() function, the general syntax of this function is as follows:

Mail() can have these parameters inside its brackets: mail(to, subject, message, headers, parameters)

MorParameter values and description are in the table below

Parameter Description
Required – The following parameters are necessary
to Receiver, or receivers of the mail
subject The main topic of the mail. Note: This parameter should not have any newline characters
message The message to be sent. Note: Each line should be separated by a line feed-LF (n). Lines should not be more than 70 characters long.
Optional – The following parameters are optional
headers Headers, such as From, Cc, and Bcc, can be specified. A carriage return line feed CRLF (rn) should be used to separate the extra headers.

Note: When sending an email, it must have a From header. This may be configured using this argument or in the php.ini file.

parameters Used to input extra  or additional parameters

An example of how to you PHP mail()

<?php

$to = ‘johndoe@email.com’;

$subject = ‘Job Offer’;

$message = ‘Would you be interested in working with us?’;

$from = ‘janejoe@email.com’;

//Sending email

if(mail($to, $subject, $message)) {

echo ‘Your mail has been sent successfully.’;

} else{

echo ‘Unable to send email. Please try again.’;

}

?>

Output:

PHP Warning: mail(): Failed to connect to mailserver at “localhost” port 25, verify your “SMTP” and “smtp_port” setting in php.ini or use ini_set() in C:UsersPromise NwhatorDocumentsArticlesPHPCodetest.php on line 8

Warning: mail(): Failed to connect to mailserver at “localhost” port 25, verify your “SMTP” and “smtp_port” setting in php.ini or use ini_set() in C:UsersPromise NwhatorDocumentsArticlesPHPCodetest.php on line 8

Unable to send email. Please try again.

From the above, you can see the PHP mail function is not working.

For PHP mail to work, it requires a delivery server (SMTP) to send out emails. If you’ve ever sent emails from an application or website while it’s in production, you’re aware of the concern that an email may be exposed to the world.

Are you sure that none of the ‘test’ emails was sent to colleagues or, still, customers? Of course, you may set up and manage a test email server for development purposes, but this is a time-consuming task. Furthermore, the time it takes to examine new test emails might significantly impede your development cycle.

To use PHP mail on your localhost, you require an SMTP(Simple Mail Transfer Protocol). The Simple Mail Transfer Protocol (SMTP) is a program that allows senders and receivers to send, receive, and redirect outgoing emails. Email is transmitted from one server to another across the Internet via SMTP whenever a mail is sent. In layman’s terms, an SMTP email is just an email sent through the SMTP server. The application I currently use on an SMTP server on my localhost is called PaperCut.

The reason why PHP mail is not working are listed below:

Some email service providers do not allow external recipients through PHP mail functions when not working with the localhost. Firstly, change the recipient ($to) from the code above to a local recipient. Simply saying, the email address to be sent to would be from the server’s domain.

Follow the steps below to send mail from the localhost XAMPP using Gmail:

  1. Open your compiler (Visual Studio Code)
  2. Locate file path “C:xamppphp” and open the “php.ini” filePhp mail not working e
  3. Locate [mail function] within the filePhp mail not working e
  4. Change the values for the following,
    • SMTP = smtp.gmail.com
    • smtp_port = 587
    • sendmail_from = “Gmail username goes here”@gmail.com
    • sendmail_path = “”C:xamppsendmailsendmail.exe” -t” – Only needed in a Unix environment
  5. Then, locate file path C:xamppsendmail and open the sendmail.ini file
  6. Locate [sendmail] within the filePhp mail not working e
  7. Change the values for the following,
    • smtp_server = smtp.gmail.com
    • smtp_port = 587
    • error_logfile = error.log (Some of this code may have been commented out, just remove the; character)
    • debug_logfile = debug.log
    • auth_username = “enter Gmail username here”@gmail.com
    • auth_password= “your Gmail password goes here”

After the setup has been completed, run the code below again:

<?php
$to = ‘johndoe@email.com’;
$subject = ‘Job Offer’;
$message = ‘Would you be interested in working with us?’;
$from = ‘janejoe@email.com’;
//Sending email
if(mail($to, $subject, $message)) {
echo ‘Your mail has been sent successfully.’;
} else{
echo ‘Unable to send email. Please try again.’;
}
?>

Steps in PHP Mail Test

The script below helps test your hosting to check that you can send emails from PHP-enabled websites with a contact form or something requiring you to send emails to users. The script is used in software, including content management systems (CMS) like WordPress, Wix, Joomla, and the likes.

If you have made adjustments (such as enabling SMTP in PHP settings), this is a fast and straightforward method to ensure the emails are correctly sent.

Create a test script (name the script test.php)  with the following code below:

<?php
ini_set(‘Show errors here’), 1);
error_reporting(E_ALL);
//Write your Email Test address here
$from = “testemail@domain.com”;
//Write the email address you are sending the email to
$to = “username@domain.com”;
$subject = “PHP Mail Test”;
$message = “This is a simple test to check if your PHP Mail works”;
//Remember the header parameter is optional
$headers = “From:” . $from;
mail($to, $subject, $message, $headers);
$sent_mail = mail ($to, $subject, $message, $headers);
$error_message = “Mail not sending”;if ($sent_mail) echo ‘Mail sent successfully!’;
else echo $error_message;
?>

Login in to your server, either your shared hosting or Virtual Private Server (VPS) preferably, and execute the code below.

PHP Mail Error Handling – The Right Way

There are different ways errors can be detected while using the PHP mail function. If your mail does not send for any reason, you can try the method below to display where the error is from.

<?php
ini_set(‘Show errors here’), 1);
error_reporting(E_ALL);
//Write your Email Test address here
$from = “testemail@domain.com”;
//Write the email address you are sending the email to
$to = “username@domain.com”;
$subject = “PHP Mail Test”;
$message = “This is a simple test to check if your PHP Mail works”;
//Remember the header parameter is optional
$headers = “From:” . $from;
mail($to, $subject, $message, $headers);
$sent_mail = mail ($to, $subject, $message, $headers);
$error_message = “Mail not sending”;
if ($sent_mail) echo ‘Mail sent successfully!’;
else echo $error_message;
?>

Because the mail above has not been connected to the service, the $error_message is expected to be displayed in the output; let’s see.

Output:

Conclusion

Without hesitation, we have concentrated on all of the strategies, methods, and actions regarding everything you need to know about PHP mail. In grasping how to resolve errors while using the PHP mail function without stress.  To wrap things up, here’s a quick rundown of what we’ve covered here so far:

  • Php mail not workingPHP mail() function allows users to send emails to users by using a script
  • PHP mail requires three (3) parameters before it can work properly. First, ‘to’ (receiver of the mail), then ‘subject’ (the main topic of the mail – This parameter should not have any newline characters), lastly, ‘message’ (The content to be sent.
  • Note: Each line should be separated by a line feed-LF (n). Lines should not be more than 70 characters long).
  • Some optional parameters may not be required to be added by the user, which are the headers and other parameters.
  • PHP mail syntax is mail(to, subject, message, headers, parameters)

We have provided enough information needed to fix errors in PHP mail. PHP mail is essential when working with contact forms on your website, either developed from scratch or through a CMS such as WordPress, Joomla, Magneto, etc.

Have fun programming.

  • Author
  • Recent Posts

Position is Everything

Your Go-To Resource for Learn & Build: CSS,JavaScript,HTML,PHP,C++ and MYSQL. Meet The Team

Position is Everything

After spending some time setting up your web server and writing up the scripts, the PHP mail function is not sending emails out as expected. Tutorials from all over the Internet show different solutions, and just what the heck is happening!? How do we fix it?

PHP mail requires a mail delivery server (SMTP) to send out emails, and there are 2 possible solutions:

  1. Install a local SMTP server.
    • Windows – Use Papercut for local testing.
    • Linux – Use sendmail or postfix, sudo apt-get install postfix.
  2. Use a remote SMTP server, simply point the SMTP settings in the php.ini file to the mail server.

That is the gist of it, but let us go through the actual steps on fixing the mail problem – Read on!

TLDR – QUICK SLIDES

Fix Mail Not Working Not Sending In PHP

Fullscreen Mode – Click Here

TABLE OF CONTENTS

INSTALLING A LOCAL SMTP SERVER

All right, let us get started with the first solution – Installing a mail server on your own machine.

WINDOWS USERS – PAPERCUT SMTP FOR LOCAL TESTING

For Windows users, try out Papercut SMTP. Papercut is probably the fastest and fuss-free SMTP server for testing. While it can be configured to relay email out, I don’t really recommend using this for a production server.

LINUX USERS – POSTFIX OR SENDMAIL

For you guys who are on Linux, simply install Sendmail or Postfix –

sudo apt-get install postfix

But different flavors of Linux has a different package manager – YUM or RPM, just use whichever is correct.

UPDATE THE PHP.INI FILE

php.ini

[mail function]
SMTP=localhost
smtp_port=25
; For Win32 only.
sendmail_from = doge@codeboxx.com

Finally in the php.ini file, simply ensure that SMTP is pointing to localhost. Also for the Windows users, set sendmail_from or you will get a “bad message return path” error message.

OTHER MAIL SERVERS – FOR PRODUCTION SERVERS

Need to set up an “actual mail server”, and not a “test mail server”? Here are a few to consider:

  • hMailServer
  • Apache James
  • Or just check Wikipedia for a whole list of mail servers.

USING A REMOTE SMTP SERVER

Don’t want to install anything? Then use an existing SMTP server that you have access to.

POINT PHP.INI TO THE SMTP SERVER

To use an existing SMTP server, just update the php.ini file and point to the SMTP server accordingly. For example, we can actually point to the Gmail SMTP server:

php.ini

[mail function]
SMTP=smtp.gmail.com
smtp_port=587
auth_username=YOUR-ID@gmail.com
auth_password=YOUR-PASSWORD

That’s it, but I will not recommend using your personal Gmail, Yahoo, or Outlook accounts on production servers… At least use one of their business accounts.

EXTRA – GMAIL AUTHENTICATION

Is Google rejecting the SMTP requests? Authentication failure? That is because Google will simply not allow any Tom, Dick, and Harry to access your email account. Thankfully, we only need to do some security setting stuff to get past this issue.

ENABLE 2-STEP AUTHENTICATION

Firstly, enable the 2-step authentication on your Google account if you have not already done so. That is basically, sending a PIN code to your mobile phone when Google detects login from an unknown device.

CREATE AN APP PASSWORD

But of course, we are not going to answer a PIN code challenge whenever we try to send an email from the server… So what we are going to do instead, is to create an app password.

Select “Other (Custom Name)” under the drop-down menu.

You can name it whatever you want…

DONE!

Finally, just copy that email/password into php.ini.

PHP MAIL DEBUGGING

Are the emails still not sent out? It’s time to get some eyes and clues on where the problem is. To do debugging on PHP mail:

  1. In your PHP script, check the error message after sending out the email – if (!mail(TO, SUBJECT, MESSAGE)) { print_r(error_get_last()); }
  2. Set mail.log = FOLDER/mail.log in php.ini.
  3. Also, set a mail log on the SMTP server itself.

That’s all. Do a test mail send and trace the log files – Did PHP send out the email? Did the SMTP server send out the email? Are the configurations correct? Lastly, also very important – Did you send it to the correct email address, is it even a valid email?

TONE DOWN FIREWALLS, ANTI-VIRUS, CHECK SPAM FOLDER

Is a firewall or anti-virus blocking the SMTP request?

  • Windows – Check and allow an exception in the Windows firewall.
  • Linux – Allow an exception in iptables.
  • Elsewhere – Maybe a hardware firewall that is somewhere in the network, or an anti-virus stopping the SMTP send.

INFOGRAPHIC CHEAT SHEET

How To Fix Mail Not Sent In PHP (Click to enlarge)

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped to solve your email problems, and if you have anything to share with this guide, please feel free to comment below. Good luck and happy coding!

Although there are portions of this answer that apply only to the usage of themail() function itself, many of these troubleshooting steps can be applied to any PHP mailing system.

There are a variety of reasons your script appears to not be sending emails. It’s difficult to diagnose these things unless there is an obvious syntax error. Without one, you need to run through the checklist below to find any potential pitfalls you may be encountering.

Make sure error reporting is enabled and set to report all errors

Error reporting is essential to rooting out bugs in your code and general errors that PHP encounters. Error reporting needs to be enabled to receive these errors. Placing the following code at the top of your PHP files (or in a master configuration file) will enable error reporting.

error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");

See How can I get useful error messages in PHP? — this answer for more details on this.

Make sure the mail() function is called

It may seem silly but a common error is to forget to actually place the mail() function in your code. Make sure it is there and not commented out.

Make sure the mail() function is called correctly

bool mail ( string $to, string $subject, string $message [, string $additional_headers [, string $additional_parameters ]] )

The mail function takes three required parameters and optionally a fourth and fifth one. If your call to mail() does not have at least three parameters it will fail.

If your call to mail() does not have the correct parameters in the correct order it will also fail.

Check the server’s mail logs

Your web server should be logging all attempts to send emails through it. The location of these logs will vary (you may need to ask your server administrator where they are located) but they can commonly be found in a user’s root directory under logs. Inside will be error messages the server reported, if any, related to your attempts to send emails.

Check for Port connection failure

Port block is a very common problem that most developers face while integrating their code to deliver emails using SMTP. And, this can be easily traced at the server maillogs (the location of the server of mail log can vary from server to server, as explained above). In case you are on a shared hosting server, ports 25 and 587 remain blocked by default. This block is been purposely done by your hosting provider. This is true even for some of the dedicated servers. When these ports are blocked, try to connect using port 2525. If you find that the port is also blocked, then the only solution is to contact your hosting provider to unblock these ports.

Most of the hosting providers block these email ports to protect their network from sending any spam emails.

Use ports 25 or 587 for plain/TLS connections and port 465 for SSL connections. For most users, it is suggested to use port 587 to avoid rate limits set by some hosting providers.

Don’t use the error suppression operator

When the error suppression operator @ is prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored. There are circumstances where using this operator is necessary but sending mail is not one of them.

If your code contains @mail(...) then you may be hiding important error messages that will help you debug this. Remove the @ and see if any errors are reported.

It’s only advisable when you check with error_get_last() right afterward for concrete failures.

Check the mail() return value

The mail() function:

Returns TRUE if the mail was successfully accepted for delivery, FALSE otherwise. It is important to note that just because the mail was accepted for delivery, it does NOT mean the mail will actually reach the intended destination.

This is important to note because:

  • If you receive a FALSE return value you know the error lies with your server accepting your mail. This probably isn’t a coding issue but a server configuration issue. You need to speak to your system administrator to find out why this is happening.
  • If you receive a TRUE return value it does not mean your email will definitely be sent. It just means the email was sent to its respective handler on the server successfully by PHP. There are still more points of failure outside of PHP’s control that can cause the email to not be sent.

So FALSE will help point you in the right direction whereas TRUE does not necessarily mean your email was sent successfully. This is important to note!

Make sure your hosting provider allows you to send emails and does not limit mail sending

Many shared webhosts, especially free webhosting providers, either do not allow emails to be sent from their servers or limit the amount that can be sent during any given time period. This is due to their efforts to limit spammers from taking advantage of their cheaper services.

If you think your host has emailing limits or blocks the sending of emails, check their FAQs to see if they list any such limitations. Otherwise, you may need to reach out to their support to verify if there are any restrictions in place around the sending of emails.

Check spam folders; prevent emails from being flagged as spam

Oftentimes, for various reasons, emails sent through PHP (and other server-side programming languages) end up in a recipient’s spam folder. Always check there before troubleshooting your code.

To avoid mail sent through PHP from being sent to a recipient’s spam folder, there are various things you can do, both in your PHP code and otherwise, to minimize the chances your emails are marked as spam. Good tips from Michiel de Mare include:

  • Use email authentication methods, such as SPF, and DKIM to prove that your emails and your domain name belong together, and to prevent spoofing of your domain name. The SPF website includes a wizard to generate the DNS information for your site.
  • Check your reverse DNS to make sure the IP address of your mail server points to the domain name that you use for sending mail.
  • Make sure that the IP-address that you’re using is not on a blacklist
  • Make sure that the reply-to address is a valid, existing address.
  • Use the full, real name of the addressee in the To field, not just the email-address (e.g. "John Smith" <john@blacksmiths-international.com> ).
  • Monitor your abuse accounts, such as abuse@yourdomain.example and postmaster@yourdomain.example. That means — make sure that these accounts exist, read what’s sent to them, and act on complaints.
  • Finally, make it really easy to unsubscribe. Otherwise, your users will unsubscribe by pressing the spam button, and that will affect your reputation.

See How do you make sure email you send programmatically is not automatically marked as spam? for more on this topic.

Make sure all mail headers are supplied

Some spam software will reject mail if it is missing common headers such as «From» and «Reply-to»:

$headers = array("From: from@example.com",
    "Reply-To: replyto@example.com",
    "X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("rn", $headers);
mail($to, $subject, $message, $headers);

Make sure mail headers have no syntax errors

Invalid headers are just as bad as having no headers. One incorrect character could be all it takes to derail your email. Double-check to make sure your syntax is correct as PHP will not catch these errors for you.

$headers = array("From from@example.com", // missing colon
    "Reply To: replyto@example.com",      // missing hyphen
    "X-Mailer: "PHP"/" . PHP_VERSION      // bad quotes
);

Don’t use a faux From: sender

While the mail must have a From: sender, you may not just use any value. In particular user-supplied sender addresses are a surefire way to get mails blocked:

$headers = array("From: $_POST[contactform_sender_email]"); // No!

Reason: your web or sending mail server is not SPF/DKIM-whitelisted to pretend being responsible for @hotmail or @gmail addresses. It may even silently drop mails with From: sender domains it’s not configured for.

Make sure the recipient value is correct

Sometimes the problem is as simple as having an incorrect value for the recipient of the email. This can be due to using an incorrect variable.

$to = 'user@example.com';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to

Another way to test this is to hard code the recipient value into the mail() function call:

mail('user@example.com', $subject, $message, $headers);

This can apply to all of the mail() parameters.

Send to multiple accounts

To help rule out email account issues, send your email to multiple email accounts at different email providers. If your emails are not arriving at a user’s Gmail account, send the same emails to a Yahoo account, a Hotmail account, and a regular POP3 account (like your ISP-provided email account).

If the emails arrive at all or some of the other email accounts, you know your code is sending emails but it is likely that the email account provider is blocking them for some reason. If the email does not arrive at any email account, the problem is more likely to be related to your code.

Make sure the code matches the form method

If you have set your form method to POST, make sure you are using $_POST to look for your form values. If you have set it to GET or didn’t set it at all, make sure you use $_GET to look for your form values.

Make sure your form action value points to the correct location

Make sure your form action attribute contains a value that points to your PHP mailing code.

<form action="send_email.php" method="POST">

Make sure the Web host supports sending email

Some Web hosting providers do not allow or enable the sending of emails through their servers. The reasons for this may vary but if they have disabled the sending of mail you will need to use an alternative method that uses a third party to send those emails for you.

An email to their technical support (after a trip to their online support or FAQ) should clarify if email capabilities are available on your server.

Make sure the localhost mail server is configured

If you are developing on your local workstation using WAMP, MAMP, or XAMPP, an email server is probably not installed on your workstation. Without one, PHP cannot send mail by default.

You can overcome this by installing a basic mail server. For Windows, you can use the free Mercury Mail.

You can also use SMTP to send your emails. See this great answer from Vikas Dwivedi to learn how to do this.

Enable PHP’s custom mail.log

In addition to your MTA’s and PHP’s log file, you can enable logging for the mail() function specifically. It doesn’t record the complete SMTP interaction, but at least function call parameters and invocation script.

ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);

See http://php.net/manual/en/mail.configuration.php for details. (It’s best to enable these options in the php.ini or .user.ini or .htaccess perhaps.)

Check with a mail testing service

There are various delivery and spamminess checking services you can utilize to test your MTA/webserver setup. Typically you send a mail probe To: their address, then get a delivery report and more concrete failures or analyses later:

  • mail-tester.example (free/simple)
  • glockapps.com (free/$$$)
  • senforensics.com (signup/$$$)
  • mailtrap.io (pro/$$$)
  • ultratools/…/emailTest (free/MX checks only)
  • Various: http://www.verticalresponse.com/blog/7-email-testing-delivery-tools/

Use a different mailer

PHP’s built-in mail() function is handy and often gets the job done but it has its shortcomings. Fortunately, there are alternatives that offer more power and flexibility including handling a lot of the issues outlined above:

  • Most popular being: PHPMailer
  • Likewise featureful: SwiftMailer
  • Or even the older PEAR::Mail.

All of these can be combined with a professional SMTP server/service provider. (Because typical 08/15 shared webhosting plans are hit or miss when it comes to email setup/configurability.)

При обработке данных, скрипт mail.php выдаёт ошибку 500 internal server error.

mail.php:

<?php
// Check for empty fields
if(empty($_POST['name'])  		||
   empty($_POST['phone']) 		||
   empty($_POST['message']) 	||
   {
	echo "No arguments Provided!";
	return false;
   }

$name = $_POST['name'];
$phone = $_POST['phone'];
$message = $_POST['message'];

// Create the email and send the message
$to = 'nemonab@gmail.com'; // Add your email address inbetween the '' replacing yourname@yourdomain.com - This is where the form will send a message to.
$email_subject = "Новый заказ";
$email_body = "С сайта поступил новый заказ, надо бы перезвонить.nn"."Данные клиента:nnИмя: $namennГород: $messagennНомер телефона: $phone";
$headers = "From: tsnochi.syte@gmail.comn"; // This is the email address the generated message will be from. We recommend using something like noreply@yourdomain.com.
$headers .= "Reply-To: email";
mail($to,$email_subject,$email_body,$headers);
return true;
?>

Код JS:

$(".contForm").validate({
    rules: {
        name: {
            required: true
        },
        phone: {
            required: true,
        },
        message: {
            required: true
        }
    },
    tooltip_options: {
    	name: {
            placement: 'top'
        },
        phone: {
            placement: 'top'
        },
        message: {
            placement: 'top',
        }
    },
    submitHandler: function(form) {
        $.ajax({
            type: "POST",
            url: "/mail.php",
            data: $(form).serialize(),
            timeout: 3000,
            success: function() {
                $(".contForm").hide();
                $(".modalContForm").hide();
                $("h2.form").hide();
                $('.form-pad').append('<h2 class="form">Заявка принята, мы Вам перезвоним!</h2>')
            },
            error: function() {
                $(".modalContForm").hide();
                $(".contForm").hide();
                $("h2.form").hide();
                $('.form-pad').append('<h2 class="form">Произошла ошибка, повторите попытку позже.</h2>')
            }
        });
        return false;
    }
});

Тривиальные ситуации, когда имеется непорядок со значением sendmail_path в конфигурации php, решаются легко. Проверьте через phpinfo();, чтобы у вас было задано значение типа /usr/sbin/sendmail -t -i в конфиге, и чтобы за /usr/sbin/sendmail действительно скрывался установленный и работающий MTA. Но сегодня пришлось побеждать менее типовую проблему: из php-скрипта почта как бы отправлялась, но где-то дальше сообщения терялись.

Убеждаемся, что PHP точно пытается отправить почту

Для начала напомню, что начиная с php 5.3 можно включить лог для всей исходящей почты, отсылаемой через функцию mail() из php. Достаточно в конфигурацию php.ini добавить такую настройку:

mail.log = /var/log/phpmail.log

При этом важно, чтобы пользователь, от которого работает php, имел доступ к файлу /var/log/phpmail.log на запись. Рекомендую для комфортной отладки создать файл и позволить всем в него записывать, примерно так:

touch /var/log/phpmail.log
chmod 666 /var/log/phpmail.log

Если у вас php работает как модуль Apache, то перезапустите последний.

Записи в логе будут примерно такие:

mail() on [/var/www/modules/system/system.mail.inc:83]: To: admin@example.tld --
Headers: From: user@example.tld

Если версия php у вас поновее чем 5.3, то в лог добавятся дата и время (что, конечно, очень полезно). Например, PHP версии 5.5.32 точно добавляет дату и время (но с какой в точности версии это началось — я не знаю). Всё-таки главное в этом логе — абсолютный адрес скрипта и номер строки, с которой вызывалась функция.

В общем, следующий тривиальный скрипт должен обязательно оставить след в логе:

<?php
  $to = 'yourmail@example.tld';
  $subject = 'Test email subject';
  $message = 'Test from PHP at ' . date('Y-m-d H:i:s');
  mail($to, $subject, $message);
  echo 'Mail sent';
?>

У меня была как раз такая ситуация: php исправно делал свою работу и записи в логе почты оставлял (ничего при этом не оставляя в логе ошибок).

Проверяем, что письмо может отправить администратор из консоли (без всяких там PHP)

Одновременно с этим почта у меня прекрасно отправлялась из серверной консоли. Проверить можно так:

echo "Test message" | mail -s "Test emal subject" yourmail@example.tld

Если вдруг на вашем сервере нет утилиты mail, то установите пакет mailx вот так:

yum -y install mailx

Анализируем лог postfix

Пришлось заглядывать в лог почтовика. Он пишется в файл /var/log/maillog (актуально для CentOS).

И вот там-то нашлись неприятные записи такого характера:

18:34:31 postfix/sendmail[26381]: fatal: chdir /var/spool/postfix: Permission denied
18:51:16 postfix/sendmail[4603]: fatal: chdir /var/spool/postfix: Permission denied

Даже минимальный опыт общения с линуксом подсказывает, что тут дело либо в несоответствии прав/владельцев, либо в какой-то дефолтной защите, типа фаерволла или… SELinux. В данном случае «виноват» последний.

Отучаем SELinux блокировать почту, отправляемую из PHP

Проверить можно такой командой:

getsebool httpd_can_sendmail

Если вывод будет httpd_can_sendmail --> off, то значит вашу почту блокирует SELinux. Чтобы его от этого отучить на постоянной основе выполните команду:

setsebool -P httpd_can_sendmail 1

И после этого ждите несколько секунд, пока снова не увидите приглашение командной строки. Без ключа -P блокировка снимется только до перезагрузки.

Кстати, пусть вас не смущает, что в параметрах SELinux упомянут httpd. Даже если у вас Apache отсутствует в принципе, а используется, например, связка nginx и php-fpm, то почта всё равно может блокироваться с аналогичными симптомами. Решается проблема точно также и для php-fpm (меняем ту же переменную).

Запрещаем виртуальному хосту отправлять почту

Иногда бывает такая ситуация, что надо наоборот запретить отправлять почту какому-то сайту. Например, если ясно, что на нём вирус, но на лечение вируса нужно время.

Тогда действуем от противного — в настройки виртуального хоста проблемного сайта добавляем параметр:

php_admin_value sendmail_path "/dev/null"

И перезапускаем Apache, чтобы изменения вступили в силу. Либо вы можете включить упомянутый выше параметр SELinux, однако, учтите, что это не поможет, если в вашей системе SELinux отсутствует или перманентно отключен.

Понравилась статья? Поделить с друзьями:
  • Полис обязательного медицинского страхования как найти номер
  • Как найти обмену в химии
  • Как можно найти ифрита
  • Как найти курьеров для доставки еды
  • Как найти многочлен равный произведению многочленов