【问题标题】:How can I send sms via php's mail function()?如何通过 php 的邮件函数()发送短信?
【发布时间】:2015-03-27 12:52:14
【问题描述】:

我最近建立了一个警报系统,当调用某些 API 时,它会通过 PHP 的 mail() 函数向我(或其他人)发出警报。

在电子邮件上它工作得很好。该函数返回true,并在发送到的邮箱中接收。

由于某种原因,当发送到 SMS 网关(即 XXXXXXXXXX@messaging.sprint.com)时,函数会发送它(它确实返回 true),但它永远不会在另一端收到。

如果我使用相同的电子邮件地址(发送到 sms 网关)并通过电子邮件客户端(例如 zimbra 或其他)发送它,它会顺利通过并被此人接收。

我是网页设计师,而不是真正的电子邮件/IT 人员。我假设它与标题或类似的东西有关,但是我不精通这个技术主题。

我与我的 IT 人员交谈,他说这是错误的,并且标题中似乎没有正确的“发件人”地址。电子邮件错误不是来自有效的电子邮件地址,而是来自“www.data@[server-name]”,而不是我通过有效电子邮件地址的标头发送的内容。

这是我的代码的 sn-p:

<?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')

然后,短信退回到“发件人”电子邮件地址,如标题中所述:

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)

这会让任何人头脑发热吗? .....

【问题讨论】:

  • 偏离您的 IT 人员所说的,您是否将“发件人”标头设置为有效地址?
  • 为了限制垃圾邮件,发件人电子邮件地址必须来自服务器。例如,如果我的服务器的主机名是“ilovespam.com”,而我使用的发件人电子邮件地址是“potus@whitehouse.gov”,则接收服务器(Sprint)会将其踢回。我会得到一个“真实”的信息,说明电子邮件已发送,但不会收到电子邮件。 PHP 无法知道电子邮件是否已收到,因为一旦发送,它就在另一台服务器上。
  • 好的,你说的是有道理的(kainaw),但我仍然在标题中输入发件人地址 - 就像发送普通电子邮件一样。我在同一个 API 上发送电子邮件,它交付得很好。只是因为我将它发送到 SMS 网关,它会改变吗?我在发送普通电子邮件时从标头值中提供相同的内容...
  • 如果您设置一个实际的电子邮件地址来发送您的 SMS,并在 PHP 中使用 SMTP 使用有效的电子邮件地址发送电子邮件,您可能会为自己省去很多邮件服务器的麻烦。我建议在 Packagist 上找到一个好的包(例如 packagist.org/packages/swiftmailer/swiftmailer
  • 这里有点跑题了,但这非常重要,所以无论如何我都会插话。您的生产代码是否会对输入进行比此代码更多的验证?如果不是,那么您真的需要投入一些,否则您将面临各种攻击!

标签: php email smtp sms


【解决方案1】:

问题很可能是由于sprintpcs DNS records are broken.这可能是故意防止人们滥用他们的服务。您可以通过使用直接连接到非权威地址的 SMTP 客户端来解决此问题。

【讨论】:

    【解决方案2】:

    首先,检查您的服务器 ip 是否在任何黑名单上。如果是这样,请尝试从他们身上移除。其次,使用有效的发件人地址表明它来自您的服务器,不要欺骗。当我这样做时,我从我的服务器发送电子邮件没有问题。

    (请注意最终用户可能需要为这些消息付费,并且收件人可能需要启用此功能)

    【讨论】:

      【解决方案3】:

      首先,我强烈建议您阅读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)

      第三,您应该考虑短信服务。例如,亚马逊有它的SNS service,您可以在其中按使用付费(还有其他按月收费的服务等)。这里的优势很明显,因为您使用的是旨在通过 SMS 推送通知的东西,而不是实现相同目的的弱(并且可能已弃用)方法。而且,这样一来,您就不必为确保您的电子邮件已格式化以便运营商接受它而烦恼。

      【讨论】:

        【解决方案4】:

        好的,首先你允许一个随机的陌生人(提交 POST 请求)通过访问 $_POST['from'] 并将其用作 FROM 地址来设置电子邮件的 FROM 地址。如果(正如其他人所建议的那样)您根据您的邮件服务器设置一个不是有效发件人地址的 FROM 地址 - 并且根据您使用的任何上游邮件服务器,这将不起作用。因此,例如,在我自己的网络中,我可以发送一封电子邮件“发件人:me@mydomain.com”,但如果我发送的邮件地址为“发件人:you@fakedomain.com”,那么它可能会被退回或被丢弃。因此,您可能需要将 From 地址硬编码为您的 IT 人员所说的任何内容,而不是使用 $_POST 变量。

        您的电子邮件实际上是“发件人:www.data@servername”这一事实可能意味着几件事:

        • 您的 PHP 已配置为使 mail() 函数调用安装在大多数 Unix/Linux 系统上的标准 sendmail 命令。
        • 运行 PHP 进程的 Apache 服务器在该系统上以“www.data”用户身份运行。
        • 该系统上的“www-data”用户无权设置备用 FROM 地址,因此 sendmail 将 FROM 地址强制为 www.data@servername,无论您告诉它什么。

        您的系统管理员需要告诉您将哪个地址硬编码为该系统上的 FROM 地址。此外,他或她需要配置邮件系统以允许 www.data 设置自己的 FROM 地址。假设您使用的是真正的 sendmail(而不是其他配置为像 sendmail 那样工作的东西,例如 postfix),那么可以通过在文件 /etc/mail/trusted-users 或在该系统上设置的任何信任文件。线索是找到系统上正在使用的 sendmail.cf 文件并查找以“Ft”开头的行,例如

        ft/etc/mail/trusted-users

        更多信息可以在 sendmail 文档中找到,例如在安装了 sendmail-cf 软件包的 Red Hat / CentOS 系统上,该系统上将有一个 /usr/share/sendmail-cf/README 文件,其中包含有关受信任用户的有用信息。

        【讨论】:

        • 谢谢 - 所有这些答案都很有帮助,这是帮助我解决它的最有帮助的 - 太......赏金去了 Delatbabel!感谢您的所有帖子。
        【解决方案5】:

        如果您知道电话号码的提供商,您可以使用大多数公司提供的电子邮件到短信服务。

        例如:

        罗杰斯无线:[10 位电话号码]@pcs.rogers.com

        Fido:[10 位电话号码]@fido.ca

        Telus:[10 位电话号码]@msg.telus.com

        Bell Mobility:[10 位电话号码]@txt.bell.ca

        工藤手机:[10 位电话号码]@msg.koodomobile.com

        MTS:[10 位电话号码]@text.mtsmobility.com

        总统选择:[10 位电话号码]@txt.bell.ca

        Sasktel:[10 位电话号码]@sms.sasktel.com

        独奏:[10 位电话号码]@txt.bell.ca

        Virgin:[10 位电话号码]@vmobile.ca

        干杯

        【讨论】:

          【解决方案6】:

          有两种解决方案(我知道):

          SMS 网关提供商或使用 GSM 调制解调器。

          对于第一个,它是最简单的,您必须使用您的提供商的 API。它也可以通过 SMTP。 该过程取决于提供者。通常,您必须提供一些额外的标头。

          使用 GSM 调制解调器(我试过),你必须向你的调制解调器启动一些命令,这并不难,但调制解调器大约 350 美元

          【讨论】:

          • 好吧,我有两个问题。一个是我在一个封闭的网络中(不是真正对互联网开放)。所以在线API调用有点困难。但如果它适用于 SMTP,那意味着什么?就像有一项服务,我可以发送带有某些标题的电子邮件,然后将其作为 SMS 转发?有什么我可以读到的吗?
          猜你喜欢
          • 2011-02-01
          • 1970-01-01
          • 2019-01-30
          • 2011-05-18
          • 2017-02-03
          • 2011-03-30
          • 1970-01-01
          • 1970-01-01
          • 2023-04-08
          相关资源
          最近更新 更多