PHP邮件功能无法在Centos服务器上运行

时间:2011-12-01 12:50:16

标签: php email centos sendmail

我正在使用centos Server并且必须将邮件发送给用户,所以我从一台服务器复制了我的运行代码,并在这里使用它,但它没有发送邮件。

代码是:

                $to = $email; //writing mail to the user
                $subject = "Hii";
                $message = "<table>
                <tr><td> Hello ".$email.",</td></tr>
                <tr><td> Some Text </td></tr>
                <tr><td> Some Text </td></tr>
                <tr><td> Some Text </td></tr>
                <tr><td> Some Text </td></tr>
                </table>" ;
                $from = "example@domain.com";
                // To send HTML mail, the Content-type header must be set
                    $headers  = 'MIME-Version: 1.0' . "\r\n";
                    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
                // Additional headers
                $headers .= 'From: Team <example@domain.com>' . "\r\n";

                if(mail($to,$subject,$message,$headers))
                {
                    echo "0";// mail sent Successfully.
                }
                else
                {
                    echo "1";
                }

始终打印1.在其他项目上运行正常的相同代码。请指导我在这里启用它能做些什么? 任何帮助将受到高度赞赏!

7 个答案:

答案 0 :(得分:24)

安装sendmail *并运行以下命令后:

[root@sendmail ~]# yum install sendmail*
[root@sendmail mail]# yum install dovecot
[root@sendmail mail]# cd /etc/mail/
[root@sendmail mail]# vi local-host-names
# local-host-names - include all aliases for your machine here.
example.com
[root@sendmail mail]# vi /etc/dovecot.conf
protocols = imap pop3 //uncomment
[root@sendmail mail]# m4 sendmail.mc > sendmail.cf
[root@sendmail mail]# make
[root@sendmail mail]# /etc/init.d/sendmail start
[root@sendmail mail]# /etc/init.d/saslauthd start
[root@sendmail mail]# /etc/init.d/dovecot start
[root@sendmail mail]# chkconfig sendmail on
[root@sendmail mail]# chkconfig dovecot on
[root@sendmail mail]# chkconfig saslauthd on

我仍有同样的问题。我查看了/var/log/maillog并看到了错误:

My unqualified host name (domain) unknown; sleeping for retry

经过更多搜索后,我更改了/etc/hosts

127.0.0.1     localhost localhost.localdomain domain
ip.ip.ip.ip  domain localhost 

为:

 127.0.0.1   localhost.localdomain localhost domain
 ip.ip.ip.ip  localhost domain  

现在邮件功能正常运行。

答案 1 :(得分:6)

我遇到了同样的问题。我在家里有一个开发服务器,在外部服务器机房有prod服务器,收到的邮件转到其他服务器。 PHP:s mail()在服务器机房很好用,但不在家里。

我测试了一下,让它以与服务器机房相同的方式在家工作。服务器机房和家庭中的方法之间的区别在于sendmail的配置。服务器机构我只需安装sendmail就可以了,但在家里我还要安装sendmail-cf并用它来添加外发邮件服务器地址。

假设您在家庭服务器上有Centos,Apache和PHP,并且您希望使用PHP:s mail()函数发送电子邮件。

1)将主服务器上的主机名设置为两个位置:/ etc / sysconfig / network和/ proc / sys / kernel / hostname这样:

 # nano /etc/sysconfig/network
   NETWORKING=yes
   HOSTNAME=mydns157.dlinkddns.com

 # nano /proc/sys/kernel/hostname
   HOSTNAME=mydns157.dlinkddns.com

2)安装sendmail和sendmail-cf:

 # yum install sendmail sendmail-cf

3)将以下行添加到/etc/mail/sendmail.mc中,在那里你有ISP:s的外发邮件服务器:

 define(`SMART_HOST',`mail.myisp.com')dnl

4)更新sendmail.cf:

 # /etc/mail/make

5)重启sendmail和apache:

 # service sendmail restart
 # service httpd restart

6)引导以更新主机名:

 # reboot

就是这样。现在以下工作:

# php -r'mail("user@somedomain.com", "Subject", "Body", null, "-fme@mydomain.com");'

你可以跳过-f:

# php -r'mail("user@somedomain.com", "Subject", "Body");'

在这种情况下,发件人的名称会自动成为user @ hostname,例如。 root@mydns157.dlinkddns.com。


主机名的一些注释

主机名的选择至关重要。 Centos6中的默认值为localhost.localdomain,但如果您在调用mail()时跳过自己的发件人地址(例如mail()),则'-fme@mydomain.com'无法使用它。如果您确定,您总是使用您的真实地址作为发件人地址来呼叫mail(),主机名可以是任何内容,但如果您现有的mail()调用缺少发件人地址(我有数百个这样的调用测试目的),那么你必须有一个真实的域作为主机名,因为在这些情况下你的服务器的主机名被用作sender-address-domain。从某种意义上说,域必须至少具有DNS A记录(由于某种原因,我的ISP不需要NS记录作为发件人地址,只需要A记录,但需要对您的ISP进行测试和检查)。使用非电子邮件域作为发件人地址的缺点是回复和传递通知将转到位天堂,但如果您在代码中删除发件人地址,通常意味着您测试和调试某些内容而不需要回复功能。域可以是例如。你从动态DNS服务器获得的那个,例如。 mydns157.dlinkddns.com,它可以指向您的家庭路由器(但不必)。您可以使用dns_get_record("mydns157.dlinkddns.com")在PHP中获取DNS记录,它返回如下数组:

 [host] => mydns157.dlinkddns.com
 [type] => A
 [ip] => 92.152.214.137
 [class] => IN
 [ttl] => 7

如果以上DNS记录中的typeNS,则该域充当电子邮件域,对于自己的服务器的主机名是可以的,但效果稍有不同。如果您将主机名设置为现有电子邮件域,例如。 myexistingemaildomain.com,并向me@myexistingemaildomain.com发送消息,例如出于调试目的,sendmail认为该消息必须传递到此服务器上用户me的邮件文件夹。如果me用户不存在,则发送失败,如果用户存在,则消息将转至/var/mail/me。这可能是你想要的,但是(像我一样)你可能希望所有的消息都是在外面而不是服务器文件夹中传递的。

您的主机名(在DNS记录中)不需要指向服务器的实际外部IP,以使mail()在缺少发件人地址的情况下工作,但不会有任何损害。主要的是hostname有一个有效的A记录,并且该域属于您。如果域名不属于您,则可能会出现安全漏洞。如果您将某个现有电子邮件域设置为主机名,例如。 microsoft.com(无论出于何种原因)并在呼叫mail()(例如'-fme@mydomain.com')时向某人发送消息而不添加您自己的发件人地址,发件人地址将自动you@microsoft.com。如果以root用户身份登录,则发件人地址将为root@microsoft.com。发送失败的回复和通知随后发送到root@microsoft.com,这可能不是您的意图。

答案 2 :(得分:6)

我知道这已经得到了解答,但我遇到了类似的问题。 如果有其他人......

/ var / log / maillog向我展示了Postfix权限问题。

sendmail: fatal: chdir /var/spool/postfix: Permission denied

追踪错误我发现解决方案是CentOS上的SELinux政策(我正在使用版本6)。

快速回答:setsebool httpd_can_sendmail 1

您可以使用-P使更改永久化;我只需要密码重置电子邮件,所以我的情况不需要。

信用:http://www.spidersoft.com.au/2011/posftix-permission-denied-problem/?ModPagespeed=noscript

编辑:我会评论,但我还没有足够的声誉。

答案 3 :(得分:2)

我建议使用SwiftMailer来解决很多问题。

require_once('../lib/swiftMailer/lib/swift_required.php');
function sendEmail(){
  //Sendmail
  $transport = Swift_SendmailTransport::newInstance('/usr/sbin/sendmail -bs');

  //Create the Mailer using your created Transport
  $mailer = Swift_Mailer::newInstance($transport);

  $body="Dear $fname,\n\nYour job application was successful. \n\nYours,\n\nEamorr\n\n\n\n\n\n\n";


  //Create a message
  $message = Swift_Message::newInstance('Subject goes here')
    ->setFrom(array($email => "no-reply@yourdomain.com"))
    ->setTo(array($email => "$fname $lname"))
    ->setBody($body);

  //Send the message
  $result = $mailer->send($message);
}

答案 4 :(得分:2)

这可以帮助你

ini_set('sendmail_from', 'example@domain.com'); 

答案 5 :(得分:2)

我刚才有这个问题,有两件事。

我的电子邮件是垃圾邮件,绝对检查一下。可能是因为我的服务器没有正确的PTR和SPF记录。

但是,我发现使用它来测试sendmail要容易得多:

sendmail -s 'me@gmail.com'
Subject:Testing!
hey there, how ya doin?
CTRL+D

答案 6 :(得分:0)

请务必检查/ var / log / maillog中的maillog以了解问题的原因。 在正确配置postfix后,我有一个类似的问题。我收到一条错误getsebool httpd_can_sendmail。解决方法是检查httpd是否可以通过setsebool -P httpd_can_sendmail 1命令启用发送邮件。如果httpd可以发送邮件关闭,则通过以下命令启用它:public class LightSwitch : NetworkBehaviour { public GameObject roomLight; void OnMouseDown () { CmdToggleLight(!roomLight.activeSelf); } [Command] void CmdToggleLight (bool status) { RpcToggleLight(status); } [ClientRpc] void RpcToggleLight (bool status) { roomLight.SetActive(status); } } 。希望这会有所帮助。