从 SMTP 服务器使用 PHP 发送电子邮件
Posted
技术标签:
【中文标题】从 SMTP 服务器使用 PHP 发送电子邮件【英文标题】:Sending email with PHP from an SMTP server 【发布时间】:2021-10-01 15:16:49 【问题描述】:$from = "someonelse@example.com";
$headers = "From:" . $from;
echo mail ("borutflis1@gmail.com" ,"testmailfunction" , "Oj",$headers);
我在 php 中发送电子邮件时遇到问题。我收到一个错误:SMTP server response: 530 SMTP authentication is required
。
我的印象是您可以在没有 SMTP 验证的情况下发送电子邮件。我知道这封邮件可能会被过滤掉,但现在没关系。
[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 = someonelse@example.com
这是php.ini
文件中的设置。我应该如何设置 SMTP?是否有任何 SMTP 服务器不需要验证或我必须自己设置服务器?
【问题讨论】:
【参考方案1】:我知道这是一个老问题,但它仍然有效,我看到的所有答案都显示基本身份验证,已弃用。下面是一个示例,展示了如何使用带有 XOAUTH2 身份验证的 PHPMailer 通过 Google 的 Gmail 服务器发送:
//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 = 'someone@gmail.com';
$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('someone@gmail.com', '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!';
参考:PHPMailer examples folder
【讨论】:
【参考方案2】:如果有人需要,我为 PHP 创建了一个简单的轻量级 SMTP 电子邮件发送器。这是网址:
https://github.com/Nerdtrix/EZMAIL
它在生产和开发两个环境中都经过了测试。
【讨论】:
【参考方案3】:当您通过需要 SMTP 身份验证的服务器发送电子邮件时,您确实需要指定它,并设置主机、用户名和密码(如果不是默认值,可能还需要端口 - 25)。
例如,我通常使用与此类似的设置的 PHPMailer:
$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->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();
您可以在此处找到有关 PHPMailer 的更多信息:https://github.com/PHPMailer/PHPMailer
【讨论】:
+1 for phpMailer -- 它是 PHP 内置mail()
函数的明智替代品。
对于那些偶然发现这个答案的人来说,值得注意的是 PHPMailer 也内置在 WordPress 中,并且可以使用 'phpmailer_init'
操作挂钩进行配置。这是为 SMTP 邮件或 Amazon SES(支持 SMTP 连接)设置 WordPress 的便捷方式。
是否允许在付费脚本中使用 PHP Mailer?
@Luka 是的,是的。根据他们的license filePHPMailer 使用 LGPL 2.1 许可证,允许商业使用。
我需要做一些特别的事情来使用这个代码吗?我把这个放在哪里?我可以使用带有 POST 请求的 HTML5 表单调用它吗?创建此 PHPMailer 对象后,如何发送电子邮件?【参考方案4】:
如果您在 Linux 上托管 WordPress 站点并具有服务器访问权限,则可以通过安装 msmtp 来省去一些麻烦,它允许您从标准 PHP mail() 函数通过 SMTP 发送。 msmtp 是 postfix 的一个更简单的替代方案,它需要更多的配置。
步骤如下:
安装 msmtp
sudo apt-get install msmtp-mta ca-certificates
创建一个新的配置文件:
sudo nano /etc/msmtprc
...带有以下配置信息:
# 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 <username@example.net>
password <password>
from <address-to-receive-bounces@example.net>
syslog LOG_MAIL
您需要替换“”中所有内容所代表的配置数据(包括,删除这些)。对于主机/用户名/密码,请使用您的正常凭据通过您的邮件提供商发送邮件。
告诉 PHP 使用它
sudo nano /etc/php5/apache2/php.ini
添加这一行:
sendmail_path = /usr/bin/msmtp -t
完整的文档可以在这里找到:
https://marlam.de/msmtp/
【讨论】:
ssmtp 也是一种解决方案,请参阅(法语指南):elliptips.info/guide-debian-7-envoi-de-mails-ligne-de-commande 这是一个非常好的解决方案,谢谢。对于 CentOS,不要忘记允许setsebool -P httpd_can_sendmail 1
setsebool -P httpd_can_sendmail 1
在 web 层为 selinux 发送电子邮件【参考方案5】:
对于另一种方法,您可以采用这样的文件:
From: Sunday <sunday@gmail.com>
To: Monday <monday@gmail.com>
Subject: Day
Tuesday Wednesday
然后像这样发送:
<?php
$a1 = ['monday@gmail.com'];
$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
【讨论】:
你好,你在 Linux 上测试了吗?【参考方案6】:这是使用 PHP PEAR 的一种方法
// Pear Mail Library
require_once "Mail.php";
$from = '<your@mail.com>'; //change this to your email address
$to = '<someone@mail.com>'; // change to address
$subject = 'Insert subject here'; // subject of mail
$body = "Hello world! this is the content of the email"; //content of mail
$headers = array(
'From' => $from,
'To' => $to,
'Subject' => $subject
);
$smtp = Mail::factory('smtp', array(
'host' => 'ssl://smtp.gmail.com',
'port' => '465',
'auth' => true,
'username' => 'your@gmail.com', //your gmail account
'password' => 'snip' // your password
));
// Send the mail
$mail = $smtp->send($to, $headers, $body);
//check mail sent or not
if (PEAR::isError($mail))
echo '<p>'.$mail->getMessage().'</p>';
else
echo '<p>Message successfully sent!</p>';
如果您使用 Gmail SMTP,请记住在您的 Gmail 帐户中启用 SMTP,在设置下
编辑: 如果你在 debian/ubuntu 上找不到 Mail.php,你可以安装 php-pear
sudo apt install php-pear
然后安装邮件扩展:
sudo pear install mail
sudo pear install Net_SMTP
sudo pear install Auth_SASL
sudo pear install mail_mime
那么你应该可以通过简单的require_once "Mail.php"
来加载它
否则它位于此处:/usr/share/php/Mail.php
【讨论】:
require_once('/usr/share/somewhere/Mail.php');【参考方案7】:<?php
ini_set("SMTP", "aspmx.l.google.com");
ini_set("sendmail_from", "YOURMAIL@gmail.com");
$message = "The mail message was sent with the following mail setting:\r\nSMTP = aspmx.l.google.com\r\nsmtp_port = 25\r\nsendmail_from = YourMail@address.com";
$headers = "From: YOURMAIL@gmail.com";
mail("Sending@provider.com", "Testing", $message, $headers);
echo "Check your email now....<BR/>";
?>
或者,更多详情,read on。
【讨论】:
您用于发送邮件的 IP 未授权 550-5.7.1 直接向我们的服务器发送电子邮件。我得到这个错误。我想要的只是一个开放的邮件中继。 我没有静态 IP。你知道任何开放式邮件中继吗? 另外参见 support.google.com/a/answer/176600?hl=en 以了解 google SMTP 中继。 这是解决 Godaddyphp mail()
功能问题的最佳答案 - 2017 - 不必下载 PHPMailer 或其他第三方资源 - 谢谢
“READ ON”链接已损坏【参考方案8】:
对于 Unix 用户,mail() 实际上是使用Sendmail 命令发送电子邮件。您可以更改环境,而不是修改应用程序。 msmtp 是一个与 Sendmail 兼容的 CLI 语法的 SMTP 客户端,这意味着它可以用来代替 Sendmail。它只需要对你的 php.ini 做一点小改动。
sendmail_path = "/usr/bin/msmtp -C /path/to/your/config -t"
那么即使是低级的 mail() 函数也可以与 SMTP 一起使用。如果您尝试将现有应用程序连接到 sendgrid 或 mandrill 等邮件服务而不修改应用程序,这将非常有用。
【讨论】:
很好的解决方案,现在在多台服务器上使用它! 在我的 Docker 容器上为不使用邮件库的应用程序实现此功能。 从 vanillamail()
到支持 SMTP 的出色迁移路径。谢谢!
MSMTP 也可用于 Windows。显而易见的下载版本为 1.4。我在某处找到的版本是 1.6.2。不知道是否有适用于 Windows 的 1.8.6。
作者在 2016 年 2 月之前停止提供 Windows 二进制文件。【参考方案9】:
问题在于 PHP mail()
函数的功能非常有限。从 PHP 发送邮件有多种方法。
mail()
在您的系统上使用 SMTP 服务器。 您至少可以在 Windows 上使用两个服务器:hMailServer 和 xmail。我花了几个小时配置和启动它们。在我看来,第一个更简单。目前,hMailServer 正在 Windows 7 x64 上运行。
mail()
在远程或 Linux 虚拟机上使用 SMTP 服务器。 当然,像 Gmail 这样的真实邮件服务不允许在没有任何凭据或密钥的情况下直接连接。您可以设置虚拟机或使用位于 LAN 中的虚拟机。大多数 linux 发行版都有开箱即用的邮件服务器。配置它并玩得开心。我在 Debian 7 上使用默认 exim4 来监听其 LAN 接口。
邮件库使用直接连接。库更容易设置。我使用了 SwiftMailer,它完美地从 Gmail 帐户发送邮件。我觉得PHPMailer也不错。
无论您选择什么,我都建议您使用一些抽象层。您可以在运行 Windows 的开发机器上使用 PHP 库,并在运行 Linux 的生产机器上简单地使用 mail()
函数。抽象层允许您根据运行应用程序的系统交换邮件驱动程序。使用抽象send()
方法创建抽象MyMailer
类或接口。继承两个类MyPhpMailer
和MySwiftMailer
。以适当的方式实现send()
方法。
【讨论】:
【参考方案10】:有些 SMTP 服务器无需身份验证即可工作,但如果服务器需要身份验证,则无法规避。
PHP 的内置邮件功能非常有限 - 只能在 WIndows 中指定 SMTP 服务器。在 *nix 上,mail()
将使用操作系统的二进制文件。
如果您想将电子邮件发送到网络上的任意 SMTP 服务器,请考虑使用像 SwiftMailer 这样的库。例如,这将使您能够使用 Google Mail 的外发服务器。
【讨论】:
以上是关于从 SMTP 服务器使用 PHP 发送电子邮件的主要内容,如果未能解决你的问题,请参考以下文章
从托管在 Hostgator 服务器上的 PHP 脚本发送 SMTP 电子邮件
使用 PHP Mailer 从本地服务器外部的电子邮件地址发送 smtp 电子邮件
发送 AUTH LOGIN 命令失败。错误:无法使用 PHP SMTP 发送电子邮件。您的服务器可能未配置为使用此方法发送邮件