Ошибка почты email php mail

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.)

I am new to PHP and I’m using the mail function to send emails which is not working. I get a success message, but still it does not work

same code

<?php
    $email_to = "abc@abc.com";
    $email_subject = "Test mail";
    $email_body = "Hello! This is a simple email message.";


    if(mail($email_to, $email_subject, $email_body)){
        echo "The email($email_subject) was successfully sent.";
    } else {
        echo "The email($email_subject) was NOT sent.";
    }
?>

Am I missing anything, do I need to include any files for this function.. I am from asp.net & this is the basic script which found on website.

I tried other scripts related to mail they didn’t work either..

I AM RUNNING THIS SCRIPT ON THE WEBSITE NOT on the localhost

Rich's user avatar

Rich

5,5859 gold badges39 silver badges61 bronze badges

asked Jan 10, 2012 at 13:27

Learning's user avatar

6

If you are using Ubuntu and it seem sendmail is not in /usr/sbin/sendmail, install sendmail using the terminal with this command:

sudo apt-get install sendmail

and then run reload the PHP page where mail() is written. Also check your spam folder.

Cody Gray - on strike's user avatar

answered Jan 19, 2014 at 19:48

Prabhat Kashyap's user avatar

Prabhat KashyapPrabhat Kashyap

9761 gold badge7 silver badges11 bronze badges

1

This is probably a configuration error. If you insist on using PHP mail function, you will have to edit php.ini.

If you are looking for an easier and more versatile option (in my opinion), you should use PHPMailer.

Cody Gray - on strike's user avatar

answered Jan 10, 2012 at 13:30

Orentet's user avatar

OrentetOrentet

2,3531 gold badge17 silver badges28 bronze badges

2

This might be the issue of your SMTP config in your php.ini file.

Since you new to PHP, You can find php.ini file in your root directory of PHP installation folder and check for SMTP = and smtp_port= and change the value to

SMTP = your mail server e.g) mail.yourdomain.com
smtp_port = 25(check your admin for original port)

In case your server require authentication for sending mail, use PEAR mail function.

answered Jan 10, 2012 at 13:40

Robin Michael Poothurai's user avatar

The mail function do not guarantee the actual delivery of mail. All it do is to pass the message to external program (usually sendmail). You need a properly configured SMTP server in order for this to work. Also keep in mind it does not support SMTP authentication. You may check out the PEAR::Mail library of SwiftMailer, both of them give you more options.

answered Jan 10, 2012 at 13:32

Maxim Krizhanovsky's user avatar

Check your SMTP settings in your php.ini file. Your host should have some documentation about what credentials to use. Perhaps you can check your error log file, it might have more information available.

answered Jan 10, 2012 at 13:31

TJHeuvel's user avatar

TJHeuvelTJHeuvel

12.3k4 gold badges37 silver badges46 bronze badges

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.)

I am new to PHP and I’m using the mail function to send emails which is not working. I get a success message, but still it does not work

same code

<?php
    $email_to = "abc@abc.com";
    $email_subject = "Test mail";
    $email_body = "Hello! This is a simple email message.";


    if(mail($email_to, $email_subject, $email_body)){
        echo "The email($email_subject) was successfully sent.";
    } else {
        echo "The email($email_subject) was NOT sent.";
    }
?>

Am I missing anything, do I need to include any files for this function.. I am from asp.net & this is the basic script which found on website.

I tried other scripts related to mail they didn’t work either..

I AM RUNNING THIS SCRIPT ON THE WEBSITE NOT on the localhost

Rich's user avatar

Rich

5,5459 gold badges37 silver badges60 bronze badges

asked Jan 10, 2012 at 13:27

Learning's user avatar

6

If you are using Ubuntu and it seem sendmail is not in /usr/sbin/sendmail, install sendmail using the terminal with this command:

sudo apt-get install sendmail

and then run reload the PHP page where mail() is written. Also check your spam folder.

Cody Gray's user avatar

Cody Gray

236k50 gold badges486 silver badges567 bronze badges

answered Jan 19, 2014 at 19:48

Prabhat Kashyap's user avatar

Prabhat KashyapPrabhat Kashyap

9761 gold badge7 silver badges11 bronze badges

1

This is probably a configuration error. If you insist on using PHP mail function, you will have to edit php.ini.

If you are looking for an easier and more versatile option (in my opinion), you should use PHPMailer.

Cody Gray's user avatar

Cody Gray

236k50 gold badges486 silver badges567 bronze badges

answered Jan 10, 2012 at 13:30

Orentet's user avatar

OrentetOrentet

2,3531 gold badge17 silver badges28 bronze badges

2

This might be the issue of your SMTP config in your php.ini file.

Since you new to PHP, You can find php.ini file in your root directory of PHP installation folder and check for SMTP = and smtp_port= and change the value to

SMTP = your mail server e.g) mail.yourdomain.com
smtp_port = 25(check your admin for original port)

In case your server require authentication for sending mail, use PEAR mail function.

answered Jan 10, 2012 at 13:40

Robin Michael Poothurai's user avatar

The mail function do not guarantee the actual delivery of mail. All it do is to pass the message to external program (usually sendmail). You need a properly configured SMTP server in order for this to work. Also keep in mind it does not support SMTP authentication. You may check out the PEAR::Mail library of SwiftMailer, both of them give you more options.

answered Jan 10, 2012 at 13:32

Maxim Krizhanovsky's user avatar

Check your SMTP settings in your php.ini file. Your host should have some documentation about what credentials to use. Perhaps you can check your error log file, it might have more information available.

answered Jan 10, 2012 at 13:31

TJHeuvel's user avatar

TJHeuvelTJHeuvel

12.2k4 gold badges37 silver badges46 bronze badges

I am new to PHP and I’m using the mail function to send emails which is not working. I get a success message, but still it does not work

same code

<?php
    $email_to = "abc@abc.com";
    $email_subject = "Test mail";
    $email_body = "Hello! This is a simple email message.";


    if(mail($email_to, $email_subject, $email_body)){
        echo "The email($email_subject) was successfully sent.";
    } else {
        echo "The email($email_subject) was NOT sent.";
    }
?>

Am I missing anything, do I need to include any files for this function.. I am from asp.net & this is the basic script which found on website.

I tried other scripts related to mail they didn’t work either..

I AM RUNNING THIS SCRIPT ON THE WEBSITE NOT on the localhost

Rich's user avatar

Rich

5,5459 gold badges37 silver badges60 bronze badges

asked Jan 10, 2012 at 13:27

Learning's user avatar

6

If you are using Ubuntu and it seem sendmail is not in /usr/sbin/sendmail, install sendmail using the terminal with this command:

sudo apt-get install sendmail

and then run reload the PHP page where mail() is written. Also check your spam folder.

Cody Gray's user avatar

Cody Gray

236k50 gold badges486 silver badges567 bronze badges

answered Jan 19, 2014 at 19:48

Prabhat Kashyap's user avatar

Prabhat KashyapPrabhat Kashyap

9761 gold badge7 silver badges11 bronze badges

1

This is probably a configuration error. If you insist on using PHP mail function, you will have to edit php.ini.

If you are looking for an easier and more versatile option (in my opinion), you should use PHPMailer.

Cody Gray's user avatar

Cody Gray

236k50 gold badges486 silver badges567 bronze badges

answered Jan 10, 2012 at 13:30

Orentet's user avatar

OrentetOrentet

2,3531 gold badge17 silver badges28 bronze badges

2

This might be the issue of your SMTP config in your php.ini file.

Since you new to PHP, You can find php.ini file in your root directory of PHP installation folder and check for SMTP = and smtp_port= and change the value to

SMTP = your mail server e.g) mail.yourdomain.com
smtp_port = 25(check your admin for original port)

In case your server require authentication for sending mail, use PEAR mail function.

answered Jan 10, 2012 at 13:40

Robin Michael Poothurai's user avatar

The mail function do not guarantee the actual delivery of mail. All it do is to pass the message to external program (usually sendmail). You need a properly configured SMTP server in order for this to work. Also keep in mind it does not support SMTP authentication. You may check out the PEAR::Mail library of SwiftMailer, both of them give you more options.

answered Jan 10, 2012 at 13:32

Maxim Krizhanovsky's user avatar

Check your SMTP settings in your php.ini file. Your host should have some documentation about what credentials to use. Perhaps you can check your error log file, it might have more information available.

answered Jan 10, 2012 at 13:31

TJHeuvel's user avatar

TJHeuvelTJHeuvel

12.2k4 gold badges37 silver badges46 bronze badges

VEG:Это зависит от настроек вашего хостера. То есть проблему отсылки почты следует обсудить с ним.

С недавних пор, у нас аналогично, в логе начали появляться аналогичные записи:

Ошибка почты
» EMAIL/PHP/mail()
/forum/cron.php»

От разных пользователей, при этом проблем с работой форума замечено не было. Может тут надо знать, куда смотреть…

Не могли бы вы объяснить, что сие обозначает. Чтоб понимать что и почему. Чтоб можно было о чем-то говорить с хостером, если что.

Спасибо.

И вот еще, в логе от Anonymous`a c дного IP адреса(192.96.201.13), записаны вот такого рода ошибки:

Произошла общая ошибка: General Error
» SQL ERROR [ mysql4 ]

Data too long for column ‘browser_id’ at row 1 [1406]

An sql error occurred while fetching this page. Please contact an administrator if this problem persists.

BACKTRACE

FILE: (not given by php)
LINE: (not given by php)
CALL: msg_handler()

FILE: [ROOT]/includes/db/dbal.php
LINE: 757
CALL: trigger_error()

FILE: [ROOT]/includes/db/mysql.php
LINE: 175
CALL: dbal->sql_error()

FILE: [ROOT]/includes/session.php
LINE: 514
CALL: dbal_mysql->sql_query()

FILE: [ROOT]/includes/session.php
LINE: 465
CALL: phpbb_session->update_browser_id()

FILE: [ROOT]/cron.php
LINE: 20
CALL: phpbb_session->session_begin()

Не вредитель ли это? На сколько это страшно/вредно ?

«Нововведения подобны новорожденным: на первых порах они необычайно нехороши собой»

Появилась на продакшен сервере вот такая ошибка

Severity: Warning
Message: mail(): Could not execute mail delivery program ‘/usr/sbin/sendmail -t -i’
Filename: libraries/Email.php
Line Number: 1545
framework code igniter

Код в этом файле такой:

if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['From'])))
{
return FALSE;
}
else
{
return TRUE;
}

Чтобы отловить ошибку пробовал ловить exception его нет
try {
тут код с майл;
}
catch (Exception $e)
{
print $e->getMessage();
}
return true;

Вывел echo все переменные на продакшене и на тестовом, вроде тут тоже все одинаковое.

Код одинаковый с тестовым сервером, на тестовом такое же окружение в такой же ос(amazon linux аналог centos) все работает и шлет. Изменений в момент когда все сломалось в окружение я не вносил.

Файл /usr/sbin/sendmail присутствует, имеет нормальные права и нормально запускается.

Функция mail используется в других частях кода и там все в порядке.
В php.ini всего две строчку для настройки mail
sendmail_path = /usr/sbin/sendmail -t -i
mail.add_x_header = On

Пробовал убирать -t -i для теста, чтобы проверить используется ли этот php.ini, после этого ошибка изменилась на не могу вызвать sendmail но без параметров -t -i

Скрипт запускаю в консоли, memory_limit 1500MB, памяти свободной куча, проца тоже, файл подкачки пустой.

конфиг php.ini не менялся несколько месяцев, конфиг sendmail также не менялся несколько месяцев.

Обновил для пущей уверенности php до 5.3.25 и sendmail до 8.14.4
Ума не приложу в какую сторону копнуть ещё или как получить больше информации об ошибке.

Май 31, 2022

Elena B.

7хв. читання

Отправка Email с PHP Mail и PHPMailer: Полное Руководство

Электронная почта — неотъемлемая часть любого проекта или бизнеса. Хотя существует множество платформ для корпоративной почты, включая Hostinger, Zoho Mail и G Suite, вы также можете отправлять письма с помощью PHP. В этом руководстве мы расскажем, как работает отправка email с PHP mail() — встроенной функции, PHPMailer и простым протоколом передачи почты (SMTP).

Функция PHP mail() вызывает программу Sendmail, обычно настраиваемую системным администратором, которая и позволяет отправлять электронные письма.

Чтобы использовать эту функцию, убедитесь, что ваш хостинг-провайдер позволяет вам вручную управлять службой Sendmail.

Возникли проблемы с отправкой писем? Hostinger предусмотрена функция PHP mail().

Если вы уже являетесь клиентом Hostinger, вы можете включить или отключить эту функцию, войдя в hPanel. Нажмите «Почта» -> «Управление почтовыми сервисами».

Раздел "Почта" в Меню hPanel

Служба Sendmail должна быть включена по умолчанию. Однако рекомендуем перепроверить это в вашей панели управления хостингом.

Страница Настройки Почтовых Служб в hPanle

Создание Тестового Файла PHP Mail

Прежде всего, вам необходимо создать файл для PHP-скрипта и поместить его в каталог public_html, чтобы к нему можно было легко получить доступ через доменное имя.

  1. В hPanel щёлкните на Файловый менеджер -> Перейдите на страницу Файлового менеджера.
  2. Создайте новый файл, нажав на иконку «Новый Файл» в верхнем меню. Назовём наш файл testmail.php и завершим процесс создания, нажав кнопку «Создать«.
    Всплывающее Окно Создания Файла в Файловом Менеджере hPanel
  3. Дважды кликните по файлу testmail.php, поскольку мы собираемся редактировать его с помощью функции PHP mail(). Вот пример основных компонентов функции, которые мы будем использовать в этом руководстве. Они будут объяснены более подробно в следующем разделе. Сейчас просто нажмите «Save & Close«, когда закончите редактировать.
    Пример Основных Компонентов Функции PHP mail в Редакторе hPanel
  4. Теперь вы можете отправить электронное письмо, открыв в браузере VashDomen/testmail.php. Не забудьте заменить «VashDomen» на доменное имя, которое вы использовали для создания тестового файла testmail.php.
  5. Теперь отправка email с PHP должна работать. Письмо должно прийти на почту получателя.
    Входящее Письмо в Gmail, Отправленное с Помощью PHP Mail

Компоненты PHP mail

Как мы и обещали, сейчас мы более подробно рассмотрим компоненты PHP-скрипта для отправки сообщений. В примере ниже вы увидите базовый синтаксис email, который поможет лучше понять эту функцию.

Однако, если вам нужна дополнительная информация о функции Sendmail и её компонентах, вы можете обратиться к официальной документации PHP.

Вот синтаксис PHP, который мы использовали в предыдущем разделе:

<?php
    ini_set( 'display_errors', 1 );
    error_reporting( E_ALL );
    $from = "test@hostinger-tutorials.com";
    $to = "test@hostinger.com";
    $subject = "Checking PHP mail";
    $message = "PHP mail works just fine";
    $headers = "From:" . $from;
    mail($to,$subject,$message, $headers);
    echo "The email message was sent.";
?>

Теперь давайте рассмотрим каждую его часть отдельно.

ini_set( 'display_errors', 1 );
error_reporting( E_ALL );

Эти первые две строки охватывают отчёты об ошибках. Они сообщат вам, если скрипт не удалось выполнить.

$from = "test@hostinger-tutorials.com";

Эта строка должна содержать адрес электронной почты отправителя. Большинство хостинг-провайдеров не разрешают использовать случайные адреса, так как это может быть использовано с целью спуфинга (англ.) — подделки писем. Всегда указывайте адреса, созданные для вашего доменного имени или бренда, тогда отправка email c PHP mail должна быть успешной.

$to = "test@gmail.com";

Здесь вы вводите адрес электронной почты получателя.

$subject = "Checking PHP mail";

Здесь мы вводим тему письма.

$message = "PHP mail works just fine";

Здесь мы вводим текст сообщения.

$headers = "From:" . $from;

Указывает важную информацию, такую как адрес отправителя.

mail ($to,$subject,$message,$headers);

Эта строка используется при выполнении функции. Оставьте её без изменений.

echo "The email message was sent.";

Сообщение, которое появится в случае успешного выполнения скрипта.

Отправка Писем с PHPMailer

PHPMailer — популярная библиотека отправки почты для PHP. Она поддерживает отправку писем, как через функцию mail(), так и через простой протокол передачи почты (SMTP). Библиотека значительно упрощает сложный процесс отправки писем с помощью PHP, предоставляя набор готовых функций для создания и отправки почты.

Установить PHPMailer довольно просто, особенно если у вас установлен Composer. Если вы используете Hostinger, вам не нужно об этом беспокоиться, поскольку он по умолчанию включен в каждый пакет хостинга.

Однако, если вам нужно установить PHPMailer вручную, тогда подключите свою учётную запись хостинга через терминал SSH. Следуй этой инструкции:

  1. Загрузите и установите SSH-клиент PuTTY.
  2. Перейдите в панель управления hPanel, найдите и кликните по «SSH-доступ» в разделе «Расширенные«.
  3. Обратите внимание на раздел с информацией для SSH-доступа. Вам понадобится SSH IP, порт, имя пользователя и пароль.
  4. Откройте PuTTY, затем укажите свой SSH IP и порт соответственно.
    Окно Настройки PuTTY
  5. Нажмите Open, появится командное окно. Введите своё имя пользователя и пароль SSH. Как только это будет сделано, нажмите Enter.
  6. ПРИМЕЧАНИЕ: PuTTY НЕ показывает пароли. Не волнуйтесь, если вы не увидите ваш пароль на экране.

  7. Выполните следующую команду:
cd public_html
  1. Нажмите Enter, затем запустите эту команду:
composer require phpmailer/phpmailer
  1. Подождите, пока процесс установки не будет завершён.
    Установка PHPMailer - Терминал

Использование PHPMailer с SMTP Hostinger

Теперь, когда PHPMailer готов к работе, вы можете начать использовать его для отправки почты средствами PHP и через Hostinger SMTP.

  1. Создайте учётную запись электронной почты, войдя в hPanel. Перейдите в раздел «Почтовые аккаунты» -> «Создать новую учётную запись электронной почты». Введите новый адрес электронной почты и установите пароль, затем нажмите «Создать».
    Страница Создания Почты в hPanel
  2. Когда закончите, обратите внимание на свои данные SMTP, расположенные на той же странице в самом вверху.
    Детали Электронной Почты

    ПРИМЕЧАНИЕ. Для того чтобы отправить письмо через PHPMailer, вам нужно знать имя пользователя учётной записи электронной почты, пароль к учётной записи, хост SMTP и порт SMTP.

  3. Создайте файл testphpmailer.php в Public_html. Откройте панель управления hPanel и щёлкните по Файловому менеджеру -> Перейдите на страницу Файлового менеджера
  4. Нажмите на иконку «Новый Файл». Назовите файл testphpmailer.php, а затем нажмите кнопку «Создать«.
  5. Дважды щёлкните по только что созданном файле testphpmailer.php, затем скопируйте и вставьте следующее:
<?php
use PHPMailerPHPMailerPHPMailer;
require 'vendor/autoload.php';
$mail = new PHPMailer;
$mail->isSMTP();
$mail->SMTPDebug = 2;
$mail->Host = 'smtp.hostinger.com';
$mail->Port = 587;
$mail->SMTPAuth = true;
$mail->Username = 'test@hostinger-tutorials.com';
$mail->Password = 'YOUR PASSWORD HERE';
$mail->setFrom('test@hostinger-tutorials.com', 'Your Name');
$mail->addReplyTo('test@hostinger-tutorials.com', 'Your Name');
$mail->addAddress('example@email.com', 'Receiver Name');
$mail->Subject = 'Testing PHPMailer';
$mail->msgHTML(file_get_contents('message.html'), __DIR__);
$mail->Body = 'This is a plain text message body';
//$mail->addAttachment('test.txt');
if (!$mail->send()) {
    echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
    echo 'The email message was sent.';
}
?>
  1. Измените приведённый выше код соответствующим образом. Например, вам нужно заменить EMAIL_ACCOUNT_PASSWORD своим паролем электронной почты или test@hostinger-tutorials.com на своё имя пользователя, example@gmail.com на адрес электронной почты получателя и т. д. После этого нажмите «Save & Close».
  2. Теперь ваш PHPMailer готов к использованию. Запустите скрипт, введя VashDomen.com/testphpmailer.php в браузере.

Компоненты PHPMailer

Чтобы понять, как работает PHPMailer, давайте разберём приведённый выше пример скрипта, который использует SMTP для отправки электронной почты. Вот подробное объяснение каждого компонента:

use PHPMailerPHPMailerPHPMailer;

Эта строка импортирует класс PHPMailer в глобальное пространство имён.

require '../vendor/autoload.php';

Включает различные библиотеки, необходимые PHPMailer.

$mail->

Все похожие переменные содержат важную информацию, такую как сведения о сервере, заголовки сообщений, вложения и многое другое. Короче говоря, они гарантируют, что отправитель защищён аутентификацией SMTP.

if (!$mail->send()) {

Определяет, что происходит при выполнении скриптов.

echo 'Mailer Error: ' . $mail->ErrorInfo;

В случае сбоя отправки скрипта отобразится сообщение об ошибке с пояснением.

} else {

Определяет, что произойдёт, если скрипт будет выполнен.

echo 'The email message was sent!';

Если письмо успешно отправлено, появится это сообщение.

СОВЕТ: строка SMTPDebug = 2; полезна лишь в том случае, если вы тестируете скрипт и хотите увидеть, как он работает. Измените её на SMTPDebug = 0; если вы закончили тест. Таким образом, конечный пользователь не увидит отчёт по SMTP.

Если вы обратили внимание, то, наверняка, заметили, что в этом примере мы делаем что-то немного по-другому. Вместо обычного текста, мы отправляем HTML-сообщение.

Следовательно, содержимое вашего сообщения будет загружаться из файла message.html, расположенного в том же каталоге — public_html.

Этот формат обеспечивает больше функциональности по сравнению с обычными текстовыми сообщениями. HTML предлагает много опций для настройки. Например, вы можете изменить цвет, стиль, изображение или даже включить мультимедийные файлы, которые обычно устаревают в обычном текстовом сообщении.

Контактная Форма PHPMailer 

Возможности PHPMailer не ограничиваются только отправкой PHP-почты. Ещё один вариант его применения — создание контактной формы, с помощью которой ваша аудитория сможет с вами связаться.

Вот пример скрипта:

<?php
use PHPMailerPHPMailerPHPMailer;
require 'vendor/autoload.php';
    $mail = new PHPMailer;
    $mail->isSMTP();
    $mail->Host = 'smtp.hostinger.com';
    $mail->Port = 587;
    $mail->SMTPAuth = true;
    $mail->Username = 'test@hostinger-tutorials.com';
    $mail->Password = 'EMAIL_ACCOUNT_PASSWORD';
    $mail->setFrom('test@hostinger-tutorials.com', 'Mr. Drago');
    $mail->addAddress('example@gmail.com', 'Receiver Name');
    if ($mail->addReplyTo($_POST['email'], $_POST['name'])) {
        $mail->Subject = 'PHPMailer contact form';
        $mail->isHTML(false);
        $mail->Body = <<<EOT
Email: {$_POST['email']}
Name: {$_POST['name']}
Message: {$_POST['message']}
EOT;
        if (!$mail->send()) {
            $msg = 'Sorry, something went wrong. Please try again later.';
        } else {
            $msg = 'Message sent! Thanks for contacting us.';
        }
    } else {
        $msg = 'Share it with us!';
    }
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Contact form</title>
</head>
<body>
<h1>Do You Have Anything in Mind?</h1>
<?php if (!empty($msg)) {
    echo "<h2>$msg</h2>";
} ?>
<form method="POST">
    <label for="name">Name: <input type="text" name="name" id="name"></label><br><br>
    <label for="email">Email: <input type="email" name="email" id="email"></label><br><br>   
    <label for="message">Message: <textarea name="message" id="message" rows="8" cols="20"></textarea></label><br><br>
    <input type="submit" value="Send">
</form>
</body>
</html>

Делаем всё то же самое, что и с предыдущими скриптами. Вам нужно создать новый файл в папке public_html. В данном случае мы назвали файл formscript.php. Отредактируйте информацию внутри скрипта соответствующим образом. После этого вам нужно только запустить скрипт из вашего браузера.

Вот как выглядит результат:

Пример Формы для КонтактовКак только ваш клиент отправит форму, он получит подтверждающее сообщение, а содержимое формы будет доставлено вам на почтовый адрес, которое вы должны указать здесь:

$mail->addAddress('example@gmail.com', 'Имя Получателя');

СОВЕТ: если контактная форма PHPMailer не работает, добавьте строку $mail->SMTPDebug = 2;, чтобы узнать, что вызывает проблему. Не забудьте удалить эту строку или поменять 2 на 0, когда закончите.

PHPMailer имеет больше примеров применения, которые вы найдёте в их официальном репозитории GitHub. Кроме того, если вы используете WordPress, вы можете легко создать контактную форму с помощью таких плагинов, как WP Forms, Formidable Form или Gravity Forms.

Главная Страница Сайта Плагина WP Forms

Устранение Распространённых Ошибок PHP Mail и PHPMailer

Отправка Email с PHP или PHPMailer время от времени может сопровождаться ошибками. Вот список наиболее распространённых проблем и способы их решения.

Адрес Отправителя Отклонён: Не Принадлежит Пользователю

Эта ошибка означает, что серверу не удалось пройти аутентификацию с использованием предоставленных данных.

Чтобы исправить это, проверьте адрес электронной почты, который вы использовали для отправки сообщения, и убедитесь, что он соответствует существующему ящику электронной почты. Если он указывает не на тот почтовый ящик, измените его соответствующим образом. Также убедитесь, что вы включили SPF-запись (англ).

Системе Gmail не Удалось Подтвердить, что Это Письмо Отправлено из Домена VashDomen.com

Если вы увидели это предупреждение при тестировании почтового скрипта PHP, это может означать одно из следующих:

  • Ваша SPF-запись не включена. Вы можете найти инструкции по её добавлению здесь (англ.).
  • Вы отправили электронное письмо с адреса, который не существует или не принадлежит вам. Убедитесь, что вы используете действительные данные аутентификации SMTP.

Сообщения Попадают в Спам

Есть несколько причин, по которым сообщения PHP могут попадать в спам. Вот некоторые из самых распространённых:

  • Тема сообщения, вводящая в заблуждение или похожая на спам. Например, когда вы указываете одно слово: «тест» или «тестирование», «привет», «срочно» или что-то подобное. Убедитесь, что ваша тема чётко отображает суть сообщения.
  • Вы используете неправильный адрес отправителя и ваше сообщение отфильтровывается как спам. Такая мера безопасности направлена на борьбу со спуфингом и мошенничеством.
  • Вы используете слова, которые работают как триггеры для фильтрации спама. В эту категорию входят такие фразы, как «отличное предложение», «нажмите здесь», «специальная акция», «это не спам» и т. д. Попробуйте изменить содержание сообщения, чтобы проверить, так ли это.
  • В вашем списке рассылки нет кнопки «Отписаться от рассылки«. Когда много людей сообщают о ваших письмах как о спаме, вам будет сложно избежать спам-фильтра. Наличие кнопки отказа от подписки — отличный способ предотвратить это и вызвать больше доверия у ваших читателей.

Заключение

Теперь вы знаете, как происходит отправка email с PHP, а также, как использовать PHPMailer для отправки писем с аутентификацией SMTP. Не смотря на то, что в этом руководстве представлены базовые примеры, тот же синтаксис можно использовать в разработке контактной формы и других расширений для вашего сайта.

Для более подробной информации не забудьте посетить страницу проекта PHPMailer. Если у вас есть какие-либо советы, рекомендации или идеи, мы будем рады услышать их в разделе комментариев ниже.

Author

Елена имеет профессиональное техническое образование в области информационных технологий и опыт программирования на разных языках под разные платформы и системы. Более 10 лет посвятила сфере веб, работая с разными CMS, такими как: Drupal, Joomla, Magento и конечно же наиболее популярной в наши дни системой управления контентом – WordPress. Её статьи всегда технически выверены и точны, будь то обзор для WordPress или инструкции по настройке вашего VPS сервера.

Хотя есть части этого ответа, которые применяются только к использованию самой функции mail(), многие из этих шагов устранения неполадок могут быть применены к любой почтовой системе PHP.

Существует множество причин, по которым ваш скрипт не отправляет электронные письма. Трудно диагностировать эти вещи, если нет очевидной синтаксической ошибки. Без этого вам нужно пройти через контрольный список ниже, чтобы найти возможные потенциальные проблемы, с которыми вы можете столкнуться.

Убедитесь, что отчет об ошибках включен и установлен для сообщения обо всех ошибках

Отчеты об ошибках необходимы для устранения ошибок в коде и общих ошибок, с которыми сталкивается PHP. Для получения этих ошибок необходимо включить отчет об ошибках. Размещение следующего кода в верхней части ваших файлов PHP (или в файле главной конфигурации) позволит включить отчет об ошибках.

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

См. Этот ответ для получения дополнительной информации об этом.

Убедитесь, что функция mail() вызывается

Это может показаться глупым, но распространенной ошибкой является забыть фактически разместить функцию mail() в вашем коде. Удостоверьтесь, что он есть и не прокомментирован.

Убедитесь, что функция mail() вызывается правильно

bool mail (string $ to, string $ subject, string $ message [, string $ дополнительные_headers [, string $ дополнительные_параметры]])

Функция почты принимает три обязательных параметра и, необязательно, четвертый и пятый. Если ваш вызов на mail() не имеет по крайней мере трех параметров, он не сработает.

Если ваш запрос на mail() не имеет правильных параметров в правильном порядке, он также потерпит неудачу.

Проверка почтовых журналов сервера

Ваш веб-сервер должен регистрировать все попытки отправки электронной почты через него. Расположение этих журналов будет отличаться (вам может потребоваться спросить администратора вашего сервера, где они находятся), но их обычно можно найти в корневом каталоге пользователя в logs. Внутри будут сообщения об ошибках, сообщенные сервером, если таковые имеются, связанные с вашими попытками отправить электронную почту.

Проверка сбоя подключения к порту

Порт-блок — очень распространенная проблема, с которой сталкиваются большинство разработчиков, интегрируя свой код для доставки электронной почты с использованием SMTP. И это можно легко проследить на сервере maillogs (расположение сервера почтового журнала может варьироваться от сервера к серверу, как объяснялось выше). Если вы находитесь на сервере общедоступного хостинга, порты 25 и 587 по умолчанию остаются заблокированными. Этот блок специально предназначен вашим хостинг-провайдером. Это справедливо даже для некоторых выделенных серверов. Когда эти порты заблокированы, попробуйте подключиться с помощью порта 2525. Если вы обнаружите, что порт также заблокирован, единственное решение — связаться с вашим хостинг-провайдером, чтобы разблокировать эти порты.

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

Используйте порты 25 или 587 для соединений с обычным /TLS и с портом 465 для соединений SSL. Для большинства пользователей предлагается использовать порт 587, чтобы избежать ограничений по скорости, установленных некоторыми хостинг-провайдерами.

Не используйте оператор подавления ошибок

Когда оператор подавления ошибок @ добавляется к выражению в PHP, любые сообщения об ошибках, которые могут быть сгенерированы этим выражением, будут игнорироваться. Существуют обстоятельства, при которых использование этого оператора необходимо, но отправка почты не является одним из них.

Если ваш код содержит @mail(...) вы можете скрывать важные сообщения об ошибках, которые помогут вам отладить это. Удалите @ и проверьте, не сообщаются ли какие-либо ошибки.

Это целесообразно только после проверки с error_get_last() сразу для конкретных отказов.

Проверьте возвращаемое значение mail()

Функция mail():

Возвращает TRUE если почта была успешно принята к доставке, в противном случае FALSE. Важно отметить, что только потому, что почта была принята для доставки, это НЕ означает, что почта действительно достигнет предполагаемого адресата.

Это важно отметить, потому что:

  • Если вы получили возвращаемое значение FALSE вы знаете, что ошибка заключается в том, что ваш сервер принимает вашу почту. Вероятно, это не проблема с кодировкой, а проблема конфигурации сервера. Вам нужно поговорить с вашим системным администратором, чтобы узнать, почему это происходит.
  • Если вы получите TRUE возвращаемое значение, это не означает, что ваш адрес электронной почты определенно будет отправлен. Это просто означает, что письмо было отправлено на соответствующий обработчик на сервере с помощью PHP. Есть еще больше проблем с ошибкой вне контроля PHP, которые могут привести к тому, что письмо не будет отправлено.

Таким образом, FALSE поможет указать вам в правильном направлении, тогда как TRUE не обязательно означает, что ваша электронная почта была успешно отправлена. Это важно отметить!

Убедитесь, что ваш хостинг-провайдер позволяет отправлять электронные письма и не ограничивает отправку почты

Многие общие веб-хосты, особенно бесплатные провайдеры веб-хостинга, не позволяют отправлять электронные письма со своих серверов или ограничивать количество, которое может быть отправлено в течение любого заданного периода времени. Это связано с их усилиями по ограничению спамеров от использования их более дешевых услуг.

Если вы считаете, что ваш хост имеет ограничения по электронной почте или блокирует отправку электронных писем, проверьте их часто задаваемые вопросы, чтобы узнать, перечисляют ли они такие ограничения. В противном случае вам может потребоваться обратиться к их поддержке, чтобы проверить, существуют ли какие-либо ограничения в отношении отправки электронных писем.

Проверьте папки спама; предотвращать помехи от сообщений электронной почты как спам

Зачастую по различным причинам электронные письма, отправленные через PHP (и другие языки программирования на стороне сервера), попадают в папку спама получателя. Всегда проверяйте их перед тем, как устранить неисправность вашего кода.

Чтобы избежать отправки почты, отправленной через PHP, в папку спама-получателя, вы можете делать различные действия, как в вашем PHP-коде, так и в других целях, чтобы минимизировать вероятность того, что ваши письма будут помечены как спам. Хорошие советы от Michiel de Mare включают:

  • Используйте методы проверки подлинности электронной почты, такие как SPF и DKIM, чтобы доказать, что ваши электронные письма и ваше доменное имя принадлежат друг другу, и для предотвращения подмены имени домена. На веб-сайте SPF есть мастер для создания DNS-информации для вашего сайта.
  • Проверьте обратный DNS, чтобы убедиться, что IP-адрес вашего почтового сервера указывает на имя домена, которое вы используете для отправки почты.
  • Убедитесь, что IP-адрес, который вы используете, не включен в черный список
  • Убедитесь, что адрес ответа — это действительный существующий адрес.
  • Используйте полное, настоящее имя адресата в поле Кому, а не только адрес электронной почты (например, "John Smith" <[email protected]>).
  • Контролируйте свои учетные записи о злоупотреблениях, такие как [email protected] и [email protected] Это означает — убедитесь, что эти учетные записи существуют, читайте, что им прислали, и поступайте по жалобам.
  • Наконец, очень легко отказаться от подписки. В противном случае ваши пользователи откажутся от подписки, нажав кнопку спама, и это повлияет на вашу репутацию.

См. Как вы уверены, что адрес электронной почты, который вы отправляете программно, автоматически не помечен как спам? для получения дополнительной информации по этой теме.

Убедитесь, что все почтовые заголовки поставлены

Некоторые спам-программы отклонят почту, если отсутствуют общие заголовки, такие как «От» и «Ответ на»:

$headers = array("From: [email protected]",
    "Reply-To: [email protected]",
    "X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("rn", $headers);
mail($to, $subject, $message, $headers);

Убедитесь, что заголовки сообщений не имеют синтаксических ошибок

Недопустимые заголовки так же плохи, как отсутствие заголовков. Одним из неправильных символов может быть все, что нужно, чтобы сорвать вашу электронную почту. Выполните двойную проверку, чтобы убедиться, что ваш синтаксис верен, поскольку PHP не поймает эти ошибки для вас.

$headers = array("From [email protected]", // missing colon
    "Reply To: [email protected]",      // missing hyphen
    "X-Mailer: "PHP"/" . PHP_VERSION      // bad quotes
);

Убедитесь, что значение получателя правильно

Иногда проблема такая же простая, как неправильное значение для получателя сообщения электронной почты. Это может быть связано с использованием неправильной переменной.

$to = '[email protected]';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to

Другой способ проверить это — записать код получателя в вызов функции mail():

mail('[email protected]', $subject, $message, $headers); 

Это может применяться ко всем параметрам mail().

Отправить на несколько аккаунтов

Чтобы устранить проблемы с электронной почтой, отправьте свое электронное письмо на несколько учетных записей электронной почты у разных поставщиков электронной почты. Если ваши электронные письма не поступают в учетную запись пользователя Gmail, отправьте те же письма на учетную запись Yahoo, учетную запись Hotmail и обычную учетную запись POP3 (например, вашу учетную запись электронной почты, предоставленную поставщиком услуг Интернета).

Если электронные письма поступают на все или другие учетные записи электронной почты, вы знаете, что ваш код отправляет электронные письма, но, скорее всего, поставщик электронной почты блокирует их по какой-либо причине. Если письмо не приходит ни на одну учетную запись электронной почты, проблема скорее связана с вашим кодом.

Убедитесь, что код соответствует методу формы

Если вы установили метод формы в POST, убедитесь, что вы используете $_POST для поиска значений формы. Если вы установили его в GET или не установили его вообще, убедитесь, что вы используете $_GET для поиска значений формы.

Убедитесь, что значение action формы указывает на правильное местоположение

Убедитесь, что атрибут action формы содержит значение, указывающее на ваш почтовый код PHP.

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

Убедитесь, что веб-хост поддерживает отправку электронной почты

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

Электронная почта к их технической поддержке (после поездки к их онлайн-поддержке или FAQ) должна уточнить, доступны ли возможности электронной почты на вашем сервере.

Убедитесь, что почтовый сервер localhost настроен

Если вы работаете на своей локальной рабочей станции с помощью WAMP, MAMP или XAMPP, сервер электронной почты, вероятно, не установлен на вашей рабочей станции. Без него PHP не может отправлять почту по умолчанию.

Вы можете преодолеть это, установив базовый почтовый сервер. Для Windows вы можете использовать бесплатную Mercury Mail.

Вы также можете использовать SMTP для отправки своих писем. Посмотрите на этот отличный ответ от Викаса Дувиди, чтобы узнать, как это сделать.

Включить собственный пользовательский mail.log

В дополнение к файлу журнала MTA и PHP вы можете включить ведение журнала для функции mail(). Он не записывает полное взаимодействие с SMTP, но, по крайней мере, выполняет функции вызова и сценарий вызова.

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

Подробнее см. Http://php.net/manual/en/mail.configuration.php. (Лучше всего включить эти опции в возможностях php.ini или .user.ini или .htaccess.)

Проверьте с помощью службы проверки почты

Существуют различные службы проверки доставки и спама, которые вы можете использовать для тестирования вашей настройки MTA/webserver. Обычно вы отправляете почтовый пробник To: их адрес, затем получаете отчет о доставке и более конкретные отказы или анализы позже:

  • mail-tester.com (бесплатный/простой)
  • glockapps.com (бесплатно/$$$)
  • senforensics.com (регистрация/$$$)
  • mailtrap.io (pro/$$$)
  • ultratools/…/emailTest (только для проверки /MX)
  • Различные: http://www.verticalresponse.com/blog/7-email-testing-delivery-tools/

Использовать другую почтовую программу

Функция PHP, встроенная в функцию mail() удобна и часто выполняет свою работу, но имеет свои недостатки. К счастью, есть альтернативы, которые предлагают больше возможностей и гибкости, включая решение многих проблем, описанных выше:

  • Наиболее популярным является: PHPMailer
  • Точно так же: SwiftMailer
  • Или даже старшая PEAR :: Mail.

Все они могут быть объединены с профессиональным SMTP-сервером/поставщиком услуг. (Поскольку типичные общие 15/15 общие планы веб-хостинга поражают или пропускают, когда дело доходит до настройки/настройки электронной почты).

  • #1

Вопрос такой, есть php-код отправки почты пользователю:

PHP:

        $checksum = base64_encode(substr($_POST['user'],0,3).$email_cnx[0]);
        $email = '[email protected]';
        $from = '[email protected]';
        $subject = 'Регистрация на сайте!';
        $subject = "=?utf-8?b?".base64_encode($subject)."?=";
        $headers = "Content-Type: text/plain; charset="utf-8"rn";
        $headers .= "MIME-Version: 1.0rn";
       	$headers .= "From: <".$from.">rn";
        $headers .= "Reply-To: ".$from."rn";
        $headers .= "Date: ". date('D, d M Y H:i:s O') ."rn";
        
        $message = "Вы зарегестрировались на сайте под именем: user1!rn";
        $message .= "Для активации вашего аккаунта пожалуйста пройдите по ссылке, указанной ниже!rn";
        $message .= "<br><a href='http://test.ru/activate.php?checksum=".$checksum."&email=".$email."'><b>Активировать аккаунт!</b></a>rn";

        if (mail($email,$subject,$message,$headers,'-f'.$from)) {echo "ПОЧТА ОТПРАВЛЕНА!!!";}
        else {echo "Отправка почты НЕ удалась!!!";}

ну обычная такая отправка почты. И суть в том, что на локальном сервере (Denwer) все отправляется, и выдается сообщение ‘Мы отправили вам письмо для подтверждения регистрации!’. То есть функция mail() возвращает значение true. Проверяю этот же код на реальном хостинге и выдается сообщение ‘Отправка почты не получилась!’. Соответственно mail() выдает false. Попытался пообщаться с техподдержкой хостинга, они сказали, что у них все должно работать, функция mail() не запрещена и sendmail настроен верно. В чем может быть проблема?

fixxxer

  • #2

зарегестрировались

facepalm.jpg

c0dex

  • #3

AdeL1ne
Поподробнее с момента, как это денвер отправляет почту с локальной машины? На сколько мне известно там простая заглушка была на сендмейл долгое время, которая просто складировала письма в одну папку.

  • #4

AdeL1ne
Поподробнее с момента, как это денвер отправляет почту с локальной машины? На сколько мне известно там простая заглушка была на сендмейл долгое время, которая просто складировала письма в одну папку.

Вообще речь о том что mail() вернул true , то что почта не ушла с машины дело другое :)
AdeL1ne
я думаю вам стоит просто попытаться вызывать mail с минимальным количеством параметров и смотреть на ошибки, ТП иногда ТП

c0dex

  • #5

tz-lom
вопрос в том, что отладка почты на денвере и фраза «у меня на нем все работало, а на сервере перестало», внушает как минимум — улыбку.

  • #6

такое наивное использование данных пришедших непонятно откуда прям «как есть»…

вы уверены, что в $_POST[’email’] хоть что-то есть?

з.ы. … отправил спамерам новый адресок… [email protected] ))

  • #7

да, на денвере почта падает в !sendmail, тоесть функция возвращает значение true, а на хостинге false. Я уже много чего подправил, но все равно, зараза, на хостинге не отрабатывается :(

  • #8

такое наивное использование данных пришедших непонятно откуда прям «как есть»…

вы уверены, что в $_POST[’email’] хоть что-то есть?

з.ы. … отправил спамерам новый адресок… [email protected] ))

дружок, ну ты пойми, свое чсв можно повышать миллионом других способов.
а конкретно по твоему вопросу — мне важно, что бы почта таки начала отправляться.
все проверки и прочая защита будут доделываться потом и сейчас нет смысла заморачиваться этим, если функция пока просто отказывается работать на хостинге!

P.S.: в первом посте отредактированный вариант отправки почты, согласно множеству рекомендаций из разных источников. Пока все-так же безрезультатно, функция выдает false :(

  • #9

проверь на простом примере из мануала:
если отправляет, ищи ошибки в твоём коде;
если не отправляет, в техподдержку хостинга с этим примером.

c0dex

  • #10

AdeL1ne
А в логи ты смотрел?

  • #11

AdeL1ne
А в логи ты смотрел?

а как их посмотреть?

отправил такой вариант:

выдало ошибку… наверно все-таки хостинг, хотя они заверяют, что все впорядке!

c0dex

  • #12

AdeL1ne
tail -n 50 /var/log/mail.log… ну или например лог от твоего php. Да и вообще хотелось бы видеть, что все таки функция mail породит в системе на хостинге.
После вызова mail(xxx) вставь print_r(error_get_last()); и посмотри, есть ли там что.

  • #13

AdeL1ne
tail -n 50 /var/log/mail.log… ну или например лог от твоего php. Да и вообще хотелось бы видеть, что все таки функция mail породит в системе на хостинге.
После вызова mail(xxx) вставь print_r(error_get_last()); и посмотри, есть ли там что.

print_r(error_get_last()); вообще ничего не выдал!
а насчет логов я так и не понял, где их смотреть конкретно на хостинге?

  • #14

служба поддержки хостинга долго тупила, но потом таки признала, что функция mail у нее отключена… всем спасибо за ответы, кое-что новое все-таки узнал.

c0dex

  • #15

Логи смотреть с консоли через ssh

Тривиальные ситуации, когда имеется непорядок со значением 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 отсутствует или перманентно отключен.

  • Ошибка потока данных как исправить
  • Ошибка почтового формата мобил легенд
  • Ошибка потеряна связь компас
  • Ошибка почтового сервера 535
  • Ошибка потеря соединения юбисофт