如何通过 php 的邮件功能 () 发送短信?
How can I send sms via php's mail function()?
我最近设置了一个警报系统,当某些 API 被调用时,它会通过 PHP 的 mail() 函数提醒我(或其他人)。
在电子邮件上它工作得很好。函数 return 为真,它在发送到的邮箱中收到。
出于某种原因,当发送到 SMS 网关(即 XXXXXXXXXX@messaging.sprint.com)时,该函数会发送它(确实 return 正确)但是它永远不会在另一端收到。
如果我使用完全相同的电子邮件地址(转到短信网关)并通过电子邮件客户端(例如 zimbra 或其他)发送它,它会顺利通过并被该人接收。
我是网页设计师,并不是真正的电子邮件/IT 人员。我假设它与 headers 或类似的东西有关,但是我不精通这个技术主题。
我和我的 IT 人员谈过,他说这是错误的,看起来 header 中没有正确的 "From" 地址。电子邮件不是来自有效的电子邮件地址,而是错误的,看起来它来自 "www.data@[server-name]" 而不是我通过有效电子邮件地址 header 发送的内容。
这是我的代码片段:
<?php
$carriers = array("@messaging.sprintpcs.com");
//get to email
if (isset($_POST['to'])) {
$to = $_POST['to'];
}
// get from email
if (isset($_POST['from'])) {
$from = $_POST['from'];
$fromHeader = "From: ".$from."\r\n Sender: ".$from."\r\n";
}
// get subject
if (isset($_POST['subject'])) {
$subject = $_POST['subject'];
}
// get message
if (isset($_POST['message'])) {
$message = $_POST['message'];
}
// get cc
if (isset($_POST['cc'])) {
if ($_POST['cc']!="") {
$ccHeader = "CC: ".$_POST['cc']."\r\n";
}
else {
$ccHeader="";
}
}
else {
$ccHeader="";
}
// get bcc
if (isset($_POST['bcc'])) {
if ($_POST['bcc']!="") {
$bccHeader = "Bcc: ".$_POST['bcc']."\r\n";
}
else {
$bccHeader="";
}
}
else {
$bccHeader="";
}
// get reply to
if (isset($_POST['replyTo'])) {
if ($_POST['replyTo']!="") {
$replyToHeader = "Reply-To: ".$_POST['replyTo']."\r\n";
}
else {
$replyToHeader="";
}
}
else {
$replyToHeader="";
}
$additionalHeaders = "Content-Type: text/plain; charset=\"utf-8\" Content-Transfer-Encoding: 8bit \r\n";
$headers = $fromHeader.$ccHeader.$bccHeader.$additionalHeaders;
foreach ($carriers as $carrier) {
$number = get_numeric_only($to).$carrier;
if (mail($to,$subject,$message,$headers)) {
$response = array("response" => "SUCCESS");
}
else {
$response = array("response" => "ERROR");
}
}
echo json_encode($response);
?>
编辑:
我通过添加第 4 个参数更改了 mail() 函数,所以它看起来像这样,显然这会有所帮助:
mail($to,$subject,$message,$headers,'-f[myaddress]@[mydomain].com')
然后 sms-email 退回到 "from" 电子邮件地址,如 header 中所述,其中包含以下内容:
The original message was received at Wed, 28 Jan 2015 19:10:32 -0500
from localhost [127.0.0.1]
----- The following addresses had permanent fatal errors -----
<xxxxxxxxxx@messaging.sprintpcs.com>
(reason: 550 Host unknown)
----- Transcript of session follows -----
550 5.1.2 <xxxxxxxxxx@messaging.sprintpcs.com>... Host unknown (Name server: messaging.sprintpcs.com: host not found)
这会让任何人头疼吗? .....
有 2 个解决方案(我知道):
SMS 网关提供商或使用 GSM 调制解调器。
对于第一个,这是最简单的一个,您必须使用您的提供商的 API。也可以通过 SMTP。
该过程取决于提供商。通常,您必须提供一些额外的 headers.
使用 GSM 调制解调器(我已经试过了),你必须向你的调制解调器启动一些命令,这并不难,但是调制解调器大约 350 美元
如果您知道 phone 号码的提供商,您可以使用大多数公司的电子邮件到短信服务。
例如:
Rogers Wireless:[10 位 phone 号码]@pcs.rogers.com
Fido:[10 位 phone 号码]@fido.ca
Telus: [10 位 phone 号码]@msg.telus.com
响铃机动性:[10 位 phone 号码]@txt.bell.ca
Kudo Mobile:[10 位 phone 号码]@msg.koodomobile.com
MTS:[10 位 phone 号码]@text.mtsmobility.com
总统选择奖:[10 位 phone 号码]@txt.bell.ca
Sasktel:[10 位 phone 号码]@sms.sasktel.com
独奏:[10 位 phone 号码]@txt.bell.ca
Virgin: [10 位 phone 号码]@vmobile.ca
干杯
好的,首先您允许随机的陌生人(提交 POST 请求的人)通过访问 $_POST['from'] 来设置电子邮件的发件人地址并将其用作发件人地址。如果(正如其他人所建议的那样)您设置的发件人地址不是根据您的邮件服务器的有效发件人地址 - 并且根据您正在使用的任何上游邮件服务器,那将不起作用。因此,例如,在我自己的网络中,我可以发送一封电子邮件 "From: me@mydomain.com",但如果我发送的地址是 "From: you@fakedomain.com",那么它可能会退回或被丢弃。因此,您可能需要将 From 地址硬编码为您的 IT 人员所说的任何内容,而不是使用 $_POST 变量。
您的电子邮件实际上以 "From: www.data@servername" 的形式发出这一事实可能意味着几件事:
- 您的 PHP 配置为 mail() 函数调用安装在大多数 Unix/Linux 系统上的标准 sendmail 命令。
- 您的 Apache 服务器,即 运行 PHP 进程,是 运行 作为该系统上的 "www.data" 用户。
- 该系统上的 "www-data" 用户无权设置备用发件人地址,因此 sendmail 强制发件人地址为 www.data@servername,无论您告诉它什么。
您的系统管理员需要告诉您硬编码哪个地址作为该系统上的发件人地址。此外,他或她需要配置邮件系统以允许 www.data 设置自己的发件人地址。假设您使用的是实际的真实 sendmail(而不是其他配置为像 sendmail 一样工作的东西,例如 postfix),那么可以通过向文件 /etc/mail/trusted-users 或任何信任文件添加一行 "www.data" 来完成在该系统上设置。线索是找到系统上正在使用的 sendmail.cf 文件并查找以 "Ft" 开头的行,例如
英尺/etc/mail/trusted-users
可以在 sendmail 文档中找到更多信息,例如在安装了 sendmail-cf 软件包的 Red Hat / CentOS 系统上,该系统上将有一个 /usr/share/sendmail-cf/README 文件,其中包含有关受信任用户的有用信息。
首先,我强烈建议您阅读 limitations on email-to-SMS。这是一个较旧的线程,但我没有理由相信现在的限制会更好。请记住,SMS 对某些用户来说不是免费的,因此运营商有一些动机来限制您可以做什么。
其次,您电子邮件的相关数据将在您的邮件服务器日志中。太多人认为因为 mail()
返回 true,所以电子邮件已发送。 mail()
所能做的就是告诉您 sendmail(或您使用的任何 MTA)是否响应。如果您查看邮件日志(对于大多数 Linux 发行版,通常在 /var/log/maillog
中)并查找您发送到的地址,您将看到 sendmail 是否真的成功发送了电子邮件或者收件人服务器拒绝了它。根据我的第一点,我敢打赌你在某种程度上被过滤了。如果您的发件人地址格式不正确,您的服务器将使用 username@server-hostname,它看起来像 apache@23247244efg.myhostingcomapny.com
(主要 YMMV,因为一些虚拟服务器不甚至没有 FQDN)
第三,你应该考虑短信服务。例如,Amazon 有其 SNS service,您可以按使用量付费(还有其他按月收费的服务等)。这里的优势很明显,因为您使用的是旨在通过 SMS 推送通知的东西,而不是实现相同功能的弱(并且可能已弃用)方法。而且,这样一来,您就不必再为确保电子邮件的格式正确而让运营商接受而头疼了。
首先,查看你的服务器ip是否在黑名单中。如果是这样,请尝试从他们那里移除。其次,使用表明其来自您的服务器的有效发件人地址,不要欺骗。当我这样做时,从我的服务器发送电子邮件没有问题。
(请注意最终用户可能需要为这些消息付费,收件人可能需要启用此功能)
问题很可能是由于 sprintpcs DNS records are broken。这可能是故意的,以防止人们滥用他们的服务。您可以使用直接连接到非权威地址的 SMTP 客户端来解决这个问题。
我最近设置了一个警报系统,当某些 API 被调用时,它会通过 PHP 的 mail() 函数提醒我(或其他人)。
在电子邮件上它工作得很好。函数 return 为真,它在发送到的邮箱中收到。
出于某种原因,当发送到 SMS 网关(即 XXXXXXXXXX@messaging.sprint.com)时,该函数会发送它(确实 return 正确)但是它永远不会在另一端收到。
如果我使用完全相同的电子邮件地址(转到短信网关)并通过电子邮件客户端(例如 zimbra 或其他)发送它,它会顺利通过并被该人接收。
我是网页设计师,并不是真正的电子邮件/IT 人员。我假设它与 headers 或类似的东西有关,但是我不精通这个技术主题。
我和我的 IT 人员谈过,他说这是错误的,看起来 header 中没有正确的 "From" 地址。电子邮件不是来自有效的电子邮件地址,而是错误的,看起来它来自 "www.data@[server-name]" 而不是我通过有效电子邮件地址 header 发送的内容。
这是我的代码片段:
<?php
$carriers = array("@messaging.sprintpcs.com");
//get to email
if (isset($_POST['to'])) {
$to = $_POST['to'];
}
// get from email
if (isset($_POST['from'])) {
$from = $_POST['from'];
$fromHeader = "From: ".$from."\r\n Sender: ".$from."\r\n";
}
// get subject
if (isset($_POST['subject'])) {
$subject = $_POST['subject'];
}
// get message
if (isset($_POST['message'])) {
$message = $_POST['message'];
}
// get cc
if (isset($_POST['cc'])) {
if ($_POST['cc']!="") {
$ccHeader = "CC: ".$_POST['cc']."\r\n";
}
else {
$ccHeader="";
}
}
else {
$ccHeader="";
}
// get bcc
if (isset($_POST['bcc'])) {
if ($_POST['bcc']!="") {
$bccHeader = "Bcc: ".$_POST['bcc']."\r\n";
}
else {
$bccHeader="";
}
}
else {
$bccHeader="";
}
// get reply to
if (isset($_POST['replyTo'])) {
if ($_POST['replyTo']!="") {
$replyToHeader = "Reply-To: ".$_POST['replyTo']."\r\n";
}
else {
$replyToHeader="";
}
}
else {
$replyToHeader="";
}
$additionalHeaders = "Content-Type: text/plain; charset=\"utf-8\" Content-Transfer-Encoding: 8bit \r\n";
$headers = $fromHeader.$ccHeader.$bccHeader.$additionalHeaders;
foreach ($carriers as $carrier) {
$number = get_numeric_only($to).$carrier;
if (mail($to,$subject,$message,$headers)) {
$response = array("response" => "SUCCESS");
}
else {
$response = array("response" => "ERROR");
}
}
echo json_encode($response);
?>
编辑:
我通过添加第 4 个参数更改了 mail() 函数,所以它看起来像这样,显然这会有所帮助:
mail($to,$subject,$message,$headers,'-f[myaddress]@[mydomain].com')
然后 sms-email 退回到 "from" 电子邮件地址,如 header 中所述,其中包含以下内容:
The original message was received at Wed, 28 Jan 2015 19:10:32 -0500
from localhost [127.0.0.1]
----- The following addresses had permanent fatal errors -----
<xxxxxxxxxx@messaging.sprintpcs.com>
(reason: 550 Host unknown)
----- Transcript of session follows -----
550 5.1.2 <xxxxxxxxxx@messaging.sprintpcs.com>... Host unknown (Name server: messaging.sprintpcs.com: host not found)
这会让任何人头疼吗? .....
有 2 个解决方案(我知道):
SMS 网关提供商或使用 GSM 调制解调器。
对于第一个,这是最简单的一个,您必须使用您的提供商的 API。也可以通过 SMTP。 该过程取决于提供商。通常,您必须提供一些额外的 headers.
使用 GSM 调制解调器(我已经试过了),你必须向你的调制解调器启动一些命令,这并不难,但是调制解调器大约 350 美元
如果您知道 phone 号码的提供商,您可以使用大多数公司的电子邮件到短信服务。
例如:
Rogers Wireless:[10 位 phone 号码]@pcs.rogers.com
Fido:[10 位 phone 号码]@fido.ca
Telus: [10 位 phone 号码]@msg.telus.com
响铃机动性:[10 位 phone 号码]@txt.bell.ca
Kudo Mobile:[10 位 phone 号码]@msg.koodomobile.com
MTS:[10 位 phone 号码]@text.mtsmobility.com
总统选择奖:[10 位 phone 号码]@txt.bell.ca
Sasktel:[10 位 phone 号码]@sms.sasktel.com
独奏:[10 位 phone 号码]@txt.bell.ca
Virgin: [10 位 phone 号码]@vmobile.ca
干杯
好的,首先您允许随机的陌生人(提交 POST 请求的人)通过访问 $_POST['from'] 来设置电子邮件的发件人地址并将其用作发件人地址。如果(正如其他人所建议的那样)您设置的发件人地址不是根据您的邮件服务器的有效发件人地址 - 并且根据您正在使用的任何上游邮件服务器,那将不起作用。因此,例如,在我自己的网络中,我可以发送一封电子邮件 "From: me@mydomain.com",但如果我发送的地址是 "From: you@fakedomain.com",那么它可能会退回或被丢弃。因此,您可能需要将 From 地址硬编码为您的 IT 人员所说的任何内容,而不是使用 $_POST 变量。
您的电子邮件实际上以 "From: www.data@servername" 的形式发出这一事实可能意味着几件事:
- 您的 PHP 配置为 mail() 函数调用安装在大多数 Unix/Linux 系统上的标准 sendmail 命令。
- 您的 Apache 服务器,即 运行 PHP 进程,是 运行 作为该系统上的 "www.data" 用户。
- 该系统上的 "www-data" 用户无权设置备用发件人地址,因此 sendmail 强制发件人地址为 www.data@servername,无论您告诉它什么。
您的系统管理员需要告诉您硬编码哪个地址作为该系统上的发件人地址。此外,他或她需要配置邮件系统以允许 www.data 设置自己的发件人地址。假设您使用的是实际的真实 sendmail(而不是其他配置为像 sendmail 一样工作的东西,例如 postfix),那么可以通过向文件 /etc/mail/trusted-users 或任何信任文件添加一行 "www.data" 来完成在该系统上设置。线索是找到系统上正在使用的 sendmail.cf 文件并查找以 "Ft" 开头的行,例如
英尺/etc/mail/trusted-users
可以在 sendmail 文档中找到更多信息,例如在安装了 sendmail-cf 软件包的 Red Hat / CentOS 系统上,该系统上将有一个 /usr/share/sendmail-cf/README 文件,其中包含有关受信任用户的有用信息。
首先,我强烈建议您阅读 limitations on email-to-SMS。这是一个较旧的线程,但我没有理由相信现在的限制会更好。请记住,SMS 对某些用户来说不是免费的,因此运营商有一些动机来限制您可以做什么。
其次,您电子邮件的相关数据将在您的邮件服务器日志中。太多人认为因为 mail()
返回 true,所以电子邮件已发送。 mail()
所能做的就是告诉您 sendmail(或您使用的任何 MTA)是否响应。如果您查看邮件日志(对于大多数 Linux 发行版,通常在 /var/log/maillog
中)并查找您发送到的地址,您将看到 sendmail 是否真的成功发送了电子邮件或者收件人服务器拒绝了它。根据我的第一点,我敢打赌你在某种程度上被过滤了。如果您的发件人地址格式不正确,您的服务器将使用 username@server-hostname,它看起来像 apache@23247244efg.myhostingcomapny.com
(主要 YMMV,因为一些虚拟服务器不甚至没有 FQDN)
第三,你应该考虑短信服务。例如,Amazon 有其 SNS service,您可以按使用量付费(还有其他按月收费的服务等)。这里的优势很明显,因为您使用的是旨在通过 SMS 推送通知的东西,而不是实现相同功能的弱(并且可能已弃用)方法。而且,这样一来,您就不必再为确保电子邮件的格式正确而让运营商接受而头疼了。
首先,查看你的服务器ip是否在黑名单中。如果是这样,请尝试从他们那里移除。其次,使用表明其来自您的服务器的有效发件人地址,不要欺骗。当我这样做时,从我的服务器发送电子邮件没有问题。
(请注意最终用户可能需要为这些消息付费,收件人可能需要启用此功能)
问题很可能是由于 sprintpcs DNS records are broken。这可能是故意的,以防止人们滥用他们的服务。您可以使用直接连接到非权威地址的 SMTP 客户端来解决这个问题。