Sending email with PHP from an SMTP server
Asked Answered
D

9

162
$from = "[email protected]";
$headers = "From:" . $from;
echo mail ("[email protected]" ,"testmailfunction" , "Oj",$headers);

I have trouble sending email in PHP. I get an error: SMTP server response: 530 SMTP authentication is required.

I was under the impression that you can send email without SMTP to verify. I know that this mail will propably get filtered out, but that doesn't matter right now.

[mail function]
; For Win32 only.
; http://php.net/smtp
SMTP = localhost
; http://php.net/smtp-port
smtp_port = 25

; For Win32 only.
; http://php.net/sendmail-from
sendmail_from = [email protected]

This is the setup in the php.ini file. How should I set up SMTP? Are there any SMTP servers that require no verification or must I setup a server myself?

Disagree answered 22/1, 2013 at 10:42 Comment(0)
A
212

When you are sending an e-mail through a server that requires SMTP Auth, you really need to specify it, and set the host, username and password (and maybe the port if it is not the default one - 25).

For example, I usually use PHPMailer with similar settings to this ones:

$mail = new PHPMailer();

// Settings
$mail->IsSMTP();
$mail->CharSet = 'UTF-8';

$mail->Host       = "mail.example.com";    // SMTP server example
$mail->SMTPDebug  = 0;                     // enables SMTP debug information (for testing)
$mail->SMTPAuth   = true;                  // enable SMTP authentication
$mail->Port       = 25;                    // set the SMTP port for the GMAIL server
$mail->Username   = "username";            // SMTP account username example
$mail->Password   = "password";            // SMTP account password example

// Content
$mail->setFrom('[email protected]');   
$mail->addAddress('[email protected]');

$mail->isHTML(true);                       // Set email format to HTML
$mail->Subject = 'Here is the subject';
$mail->Body    = 'This is the HTML message body <b>in bold!</b>';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';

$mail->send();

You can find more about PHPMailer here: https://github.com/PHPMailer/PHPMailer

Aletheaalethia answered 22/1, 2013 at 10:46 Comment(6)
It's worth noting for those stumbling on this answer that PHPMailer is also built into WordPress and can be configured using the 'phpmailer_init' action hook. It's a convenient way to set up WordPress for SMTP mail or Amazon SES (which supports SMTP connections).Gass
Is PHP Mailer allowed to be used in paid scripts?Donn
@Donn Yes, it is. According to their license file PHPMailer uses the LGPL 2.1 license, which allows commercial usage.Sliver
Do I need to do anything special to use this code? Where do I put this? Can I call it with an HTML5 form with a POST request? How do I send an Email once I created this PHPMailer object?Cephalalgia
And how do you actually set the message and send the email??!Moldboard
@Moldboard just added that to the example.Aletheaalethia
G
67
<?php
ini_set("SMTP", "aspmx.l.google.com");
ini_set("sendmail_from", "[email protected]");

$message = "The mail message was sent with the following mail setting:\r\nSMTP = aspmx.l.google.com\r\nsmtp_port = 25\r\nsendmail_from = [email protected]";

$headers = "From: [email protected]";

mail("[email protected]", "Testing", $message, $headers);
echo "Check your email now....&lt;BR/>";
?>

or, for more details, read on.

Gonion answered 22/1, 2013 at 11:21 Comment(10)
The IP you're using to send mail is not authorized to 550-5.7.1 send email directly to our servers. I get this error. all I want is a open mail relay.Disagree
I dont have a static IP. Do you know of any Open mail relay.Disagree
are you using email as SMTP./Gonion
Additionally see support.google.com/a/answer/176600?hl=en for google SMTP relays.Terrence
Thanks a lot. I got the same error "using to send mail is not authorized to 550-5.7.1". Your answer is worked perfectly.Accrescent
Open relays are often used for spam purposes. I don't think we should be helping, or encouraging, the use of open relays for sending email. What is the OP trying to do that he cannot use an authenticated SMTP server?Aerostation
This is the best answer for godaddy php mail() function issues - 2017 - shouldn't have to download PHPMailer or some other 3rd party resource - thanksInlay
"READ ON" link is brokenSolidary
It does not need password to send out e-mail? why?Psalter
this worked like a charm!Raff
E
55

For Unix users, mail() is actually using Sendmail command to send email. Instead of modifying the application, you can change the environment. msmtp is an SMTP client with Sendmail compatible CLI syntax which means it can be used in place of Sendmail. It only requires a small change to your php.ini.

sendmail_path = "/usr/bin/msmtp -C /path/to/your/config -t"

Then even the lowly mail() function can work with SMTP goodness. It is super useful if you're trying to connect an existing application to mail services like sendgrid or mandrill without modifying the application.

Edify answered 2/12, 2013 at 21:52 Comment(5)
Great solution, use it on multiple servers now!Theatrics
Implementing this on my Docker containers for apps that don't use a mailing library.Fabricate
Excellent migration path from vanilla mail() to something that supports SMTP. Thank you!Supervisor
MSMTP is also available for Windows. The obvious downloads have version 1.4. The version I found somewhere is 1.6.2. Don't know if there is a 1.8.6 for Windows.Fenestra
The author stopped providing Windows binaries before 2016 February.Fenestra
D
19

The problem is that PHP mail() function has a very limited functionality. There are several ways to send mail from PHP.

  1. mail() uses SMTP server on your system. There are at least two servers you can use on Windows: hMailServer and xmail. I spent several hours configuring and getting them up. First one is simpler in my opinion. Right now, hMailServer is working on Windows 7 x64.
  2. mail() uses SMTP server on remote or virtual machine with Linux. Of course, real mail service like Gmail doesn't allow direct connection without any credentials or keys. You can set up virtual machine or use one located in your LAN. Most linux distros have mail server out of the box. Configure it and have fun. I use default exim4 on Debian 7 that listens its LAN interface.
  3. Mailing libraries use direct connections. Libs are easier to set up. I used SwiftMailer and it perfectly sends mail from Gmail account. I think that PHPMailer is pretty good too.

No matter what choice is your, I recommend you use some abstraction layer. You can use PHP library on your development machine running Windows and simply mail() function on production machine with Linux. Abstraction layer allows you to interchange mail drivers depending on system which your application is running on. Create abstract MyMailer class or interface with abstract send() method. Inherit two classes MyPhpMailer and MySwiftMailer. Implement send() method in appropriate ways.

Driblet answered 22/1, 2014 at 20:44 Comment(0)
F
12

There are some SMTP servers that work without authentication, but if the server requires authentication, there is no way to circumvent that.

PHP's built-in mail functions are very limited - specifying the SMTP server is possible in WIndows only. On *nix, mail() will use the OS's binaries.

If you want to send E-Mail to an arbitrary SMTP server on the net, consider using a library like SwiftMailer. That will enable you to use, for example, Google Mail's outgoing servers.

Faulty answered 22/1, 2013 at 10:44 Comment(0)
R
4

In cases where you are hosting a WordPress site on Linux and have server access, you can save some headaches by installing msmtp which allows you to send via SMTP from the standard PHP mail() function. msmtp is a simpler alternative to postfix which requires a bit more configuration.

Here are the steps:

Install msmtp

sudo apt-get install msmtp-mta ca-certificates

Create a new configuration file:

sudo nano /etc/msmtprc

...with the following configuration information:

# Set defaults.
defaults

# Enable or disable TLS/SSL encryption.
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt

# Set up a default account's settings.
account default
host <smtp.example.net>
port 587
auth on
user <[email protected]>
password <password>
from <[email protected]>
syslog LOG_MAIL

You need to replace the configuration data represented by everything within "<" and ">" (inclusive, remove these). For host/username/password, use your normal credentials for sending mail through your mail provider.

Tell PHP to use it

sudo nano /etc/php5/apache2/php.ini

Add this single line:

sendmail_path = /usr/bin/msmtp -t

Complete documentation can be found here:

https://marlam.de/msmtp/

Rachele answered 28/9, 2018 at 2:34 Comment(2)
ssmtp is also a solution see (French guide) : elliptips.info/guide-debian-7-envoi-de-mails-ligne-de-commandeSpondylitis
This is a very nice solution, thank you. For CentOS don't forget to allow sending e-mail on web layer for selinux by setsebool -P httpd_can_sendmail 1Unipod
L
2

I know this is an old question but it's still active and all the answers I saw showed basic authentication, which is deprecated. Here is an example showing how to send via Google's Gmail servers using PHPMailer with XOAUTH2 authentication:

//Import PHPMailer classes into the global namespace
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\OAuth;
//Alias the League Google OAuth2 provider class
use League\OAuth2\Client\Provider\Google;

//SMTP needs accurate times, and the PHP time zone MUST be set
//This should be done in your php.ini, but this is how to do it if you don't have access to that
date_default_timezone_set('Etc/UTC');

//Load dependencies from composer
//If this causes an error, run 'composer install'
require '../vendor/autoload.php';

//Create a new PHPMailer instance
$mail = new PHPMailer();

//Tell PHPMailer to use SMTP
$mail->isSMTP();

//Enable SMTP debugging
//SMTP::DEBUG_OFF = off (for production use)
//SMTP::DEBUG_CLIENT = client messages
//SMTP::DEBUG_SERVER = client and server messages
$mail->SMTPDebug = SMTP::DEBUG_SERVER;

//Set the hostname of the mail server
$mail->Host = 'smtp.gmail.com';

//Set the SMTP port number:
// - 465 for SMTP with implicit TLS, a.k.a. RFC8314 SMTPS or
// - 587 for SMTP+STARTTLS
$mail->Port = 465;

//Set the encryption mechanism to use:
// - SMTPS (implicit TLS on port 465) or
// - STARTTLS (explicit TLS on port 587)
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;

//Whether to use SMTP authentication
$mail->SMTPAuth = true;

//Set AuthType to use XOAUTH2
$mail->AuthType = 'XOAUTH2';

//Fill in authentication details here
//Either the gmail account owner, or the user that gave consent
$email = '[email protected]';
$clientId = 'RANDOMCHARS-----duv1n2.apps.googleusercontent.com';
$clientSecret = 'RANDOMCHARS-----lGyjPcRtvP';

//Obtained by configuring and running get_oauth_token.php
//after setting up an app in Google Developer Console.
$refreshToken = 'RANDOMCHARS-----DWxgOvPT003r-yFUV49TQYag7_Aod7y0';

//Create a new OAuth2 provider instance
$provider = new Google(
    [
        'clientId' => $clientId,
        'clientSecret' => $clientSecret,
    ]
);

//Pass the OAuth provider instance to PHPMailer
$mail->setOAuth(
    new OAuth(
        [
            'provider' => $provider,
            'clientId' => $clientId,
            'clientSecret' => $clientSecret,
            'refreshToken' => $refreshToken,
            'userName' => $email,
        ]
    )
);

//Set who the message is to be sent from
//For gmail, this generally needs to be the same as the user you logged in as
$mail->setFrom($email, 'First Last');

//Set who the message is to be sent to
$mail->addAddress('[email protected]', 'John Doe');

//Set the subject line
$mail->Subject = 'PHPMailer GMail XOAUTH2 SMTP test';

//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
$mail->CharSet = PHPMailer::CHARSET_UTF8;
$mail->msgHTML(file_get_contents('contentsutf8.html'), __DIR__);

//Replace the plain text body with one created manually
$mail->AltBody = 'This is a plain-text message body';

//Attach an image file
$mail->addAttachment('images/phpmailer_mini.png');

//send the message, check for errors
if (!$mail->send()) {
    echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
    echo 'Message sent!';
}

Reference: PHPMailer examples folder

Larkins answered 20/1, 2022 at 22:8 Comment(0)
D
1

For another approach, you can take a file like this:

From: Sunday <[email protected]>
To: Monday <[email protected]>
Subject: Day

Tuesday Wednesday

and send like this:

<?php
$a1 = ['[email protected]'];
$r1 = fopen('a.txt', 'r');
$r2 = curl_init('smtps://smtp.gmail.com');
curl_setopt($r2, CURLOPT_MAIL_RCPT, $a1);
curl_setopt($r2, CURLOPT_NETRC, true);
curl_setopt($r2, CURLOPT_READDATA, $r1);
curl_setopt($r2, CURLOPT_UPLOAD, true);
curl_exec($r2);

https://php.net/function.curl-setopt

Discourtesy answered 3/8, 2020 at 22:56 Comment(1)
Hello, did you test in on Linux?Repress
V
0

I created a simple lightweight SMTP email sender for PHP if anybody needs it. Here is the URL:

https://github.com/Nerdtrix/EZMAIL

It was tested in both environments, production and development.

Vice answered 4/12, 2020 at 21:38 Comment(2)
I wanted to try your EZMAIL, but returns me this error require(vendor/autoload.php): failed to open stream: No such file or directory, I miss something?Accompanyist
hi @SzabolcsHorvath you must install composer for this otherwise it will not work.Vice

© 2022 - 2024 — McMap. All rights reserved.