nginx - 无法从 Nginx php - 基于 fpm 的 dedi 发送电子邮件?

标签 nginx php dedicated-server

我有一个站点,它有联系页面。在该页面中有电子邮件和评论选项卡。每当有人输入他的电子邮件和评论并单击提交邮件时,都应该发送到我的电子邮件中。但它不起作用。

我将此 php 文件用于邮件功能。

我在我的专用服务器上安装了 nginx 和 php - fpm。

<?php
/*
This first bit sets the email address that you want the form to be submitted to.
You will need to change this value to a valid email address that you can access.
*/
$webmaster_email = "myemail@yahoo.com";

/*
This bit sets the URLs of the supporting pages.
If you change the names of any of the pages, you will need to change the values here.
*/
$feedback_page = "contact.html";
$error_page = "error_message.html";
$thankyou_page = "thank_you.html";

/*
This next bit loads the form field data into variables.
If you add a form field, you will need to add it here.
*/
$email_address = $_REQUEST['email_address'] ;
$comments = $_REQUEST['comments'] ;

/*
The following function checks for email injection.
Specifically, it checks for carriage returns - typically used by spammers to inject a CC list.
*/
function isInjected($str) {
    $injections = array('(\n+)',
    '(\r+)',
    '(\t+)',
    '(%0A+)',
    '(%0D+)',
    '(%08+)',
    '(%09+)'
    );
    $inject = join('|', $injections);
    $inject = "/$inject/i";
    if(preg_match($inject,$str)) {
        return true;
    }
    else {
        return false;
    }
}

// If the user tries to access this script directly, redirect them to the feedback form,
if (!isset($_REQUEST['email_address'])) {
header( "Location: $feedback_page" );
}

// If the form fields are empty, redirect to the error page.
elseif (empty($email_address) || empty($comments)) {
header( "Location: $error_page" );
}

// If email injection is detected, redirect to the error page.
elseif ( isInjected($email_address) ) {
header( "Location: $error_page" );
}

// If we passed all previous tests, send the email then redirect to the thank you page.
else {
mail( "$webmaster_email", "Feedback Form Results",
  $comments, "From: $email_address" );
header( "Location: $thankyou_page" );
}
?>

但是我的电子邮箱没有收到邮件。当我有 apache 时它正在工作。我是 nginx 的新手。那么我怎样才能让它适用于 nginx。

如有任何帮助,我们将不胜感激。

最佳答案

这里是使用 mail() 函数的一个非常好的替代方法。

配置见最后一个函数。

<?php

  class Xmail{

    # LOG VAR
    public $log = Array();

    # NEW LINE
    private $line = "\r\n";

    # ATTACHED FILES
    public $files = Array();

    # CONFIG GENERAL
    private $tpl = "";
    private $mode = "mail";

    function setTPL($value) { if($value != "") $this->tpl = $value; }
    function setMODE($value) { if($value != "") $this->mode = $value; }

    # CONFIG SMTP
    private $smtp_host = "localhost";
    private $smtp_port = "25";
    private $smtp_username = "";
    private $smtp_password = "";

    function setSmtpHost($value) { if($value != "") $this->smtp_host = $value; }
    function setSmtpPort($value) { if($value != "") $this->smtp_port = $value; }
    function setSmtpUser($value) { if($value != "") $this->smtp_username = $value; }
    function setSmtpPass($value) { if($value != "") $this->smtp_password = $value; }

    # CONFIG SOCKET
    private $from = "sokmail@localhost"; // sender email address
    private $host = "localhost"; // your domain name here
    private $port = "25"; // it is always 25 but i think it's best to have this for tests when developper pc has port 25 blocked and server has alternate port [i use 26 cause 25 is locked for anti SPAM by ISP]
    private $time = "30"; // timeout [time short :D]
    private $test = false; // test mode, does not send the email but you can see the log up to the point of sending email, good to check email addresses if valid or server if black-listed

    function setFrom($value) { if($value != "") $this->from = $value; }
    function setHost($value) { if($value != "") $this->host = $value; }
    function setPort($value) { if($value != "") $this->port = $value; }
    function setTime($value) { if($value != "") $this->time = $value; }
    function setTest($value) { if($value != "") $this->test = $value; }

    # MAIN FUNCTION
    function mail($to, $subject, $msg, $headers, $attachments = NULL) {

      # MESSAGE HTML
      $msg = str_replace("\'","'",$msg);
      $msg = str_replace('\"','"',$msg);

      # Use template if case
      if(is_file($this->tpl)){
        $html = implode("", file($this->tpl));
        $html = str_replace("{MESSAGE}", $msg, $html);
      }else
       $html = $msg;

      $boundary1 = '-----='.md5(uniqid(rand()));
      $boundary2 = '-----='.md5(uniqid(rand()));

      $message .= "\r\nThis is a multi-part message in MIME format.\r\n\r\n";
      $message .= "--".$boundary1."\r\n";
      $message .= "Content-Type: multipart/alternative;\r\n      boundary=\"$boundary2\"\r\n\r\n";

      # MESSAGE TEXT
      $message .= "--".$boundary2."\r\n";
      $message .= "Content-Type: text/plain;\r\n      charset=\"UTF-8\"\r\n";
      $message .= "Content-Transfer-Encoding: 7bit\r\n";
      $message .= strip_tags($msg) . "\r\n";
      $message .= "\r\n\r\n";

      # MESSAGE HTML
      $message .= "--".$boundary2."\r\n";
      $message .= "Content-Type: text/html;\r\n      charset=\"UTF-8\"\r\n";
      $message .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";
      $message .= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\r\n";
      $message .= "<html>\r\n";
      $message .= "<body>\r\n";
      $message .= str_replace("
", "<br/>", $html) . "<br/>\r\n";
      $message .= "</body>\r\n";
      $message .= "</html>\r\n\r\n";
      $message .= "--".$boundary2."--\r\n\r\n";

      if(is_array($attachments)) {
        foreach($attachments AS $file_url) {
          if(is_file($file_url)) {
            $file_name = pathinfo($file_url, PATHINFO_BASENAME);
            $file_type = $this->find_mime(pathinfo($file_url, PATHINFO_EXTENSION));

            # ATTACHMENT
            $message .= "--".$boundary1."\r\n";
            $message .= "Content-Type: ".$file_type.";\r\n      name=\"$file_name\"\r\n";
            $message .= "Content-Transfer-Encoding: base64\r\n";
            $message .= "Content-Disposition: attachment;\r\n      filename=\"$file_name\"\r\n\r\n";

            $fp = fopen($file_url, 'r');
            do {
              $data = fread($fp, 8192);
              if (strlen($data) == 0) break;
              $content .= $data;
            }
            while (true);
            $content_encode = chunk_split(base64_encode($content));
            $message .= $content_encode."\r\n\r\n";
            $content = '';
            unset($content); 

          }
        }
      }
      $message .= "--".$boundary1."--\r\n\r\n";

      $headers .= "MIME-Version: 1.0\r\n";
      $headers .= "Content-Type: multipart/mixed;\r\n      boundary=\"$boundary1\"\r\n";

      if($this->mode == "smtp" || $this->mode == "mx")
       return $this->sokmail($to, $subject, $message, $headers);
      else {
        if(mail($to, $subject, $message, $headers)) return true;
        return false;
      }
    }

    # send mail directly to destination MX server
    function sokmail($to, $subject, $message, $headers) {
      // get server based on mode
      if($this->mode == "mx") {
        list($user, $domain) = split("@",$to);
        getmxrr($domain, $mxhosts);
        $server = $mxhosts['0'];
      }else{
        $server = $this->smtp_host;
      }

      # open socket
      $socket = @fsockopen($server, $this->port, $errno, $errstr, $this->time);
      if(empty($socket)) { return false; }
      if($this->parse_response($socket, 220, "SOCKET") != 220) { fclose($socket); return false; }

      # say HELO to our little friend
      fputs($socket, "EHLO " . $this->host . $this->line);
      if($this->parse_response($socket, 250, "HELO") != 250) { fclose($socket); return false; }

      # if SMTP
      if($this->mode == "smtp" && !empty($this->smtp_username) && !empty($this->smtp_password) ) {
        # start login
        fputs($socket, "AUTH LOGIN" . $this->line);
        if($this->parse_response($socket, 334, "AUTH LOGIN") != 334) { fclose($socket); return false; }

        fputs($socket, base64_encode($this->smtp_username) . $this->line);
        if($this->parse_response($socket, 334, "USERNAME") != 334) { fclose($socket); return false; }

        fputs($socket, base64_encode($this->smtp_password) . $this->line);
        if($this->parse_response($socket, 235, "PASSWORD") != 235) { fclose($socket); return false; }
      }

      # email from
      fputs($socket, "MAIL FROM: <" . $this->from . ">" . $this->line);
      if($this->parse_response($socket, 250, "MAIL FROM") != 250) { fclose($socket); return false; }

      # email to
      fputs($socket, "RCPT TO: <" . $to . ">" . $this->line);
      if($this->parse_response($socket, 250, "RCPT TO") != 250) { fclose($socket); return false; }

      # check for test mode
      if($this->test != true) {

        # send data start command
        fputs($socket, "DATA" . $this->line);
        if($this->parse_response($socket, 354, "DATA") != 354) { fclose($socket); return false; }

        # make the deposit :)
        fputs($socket, "Subject: " . $subject . $this->line);
        fputs($socket, "To: " . $to . $this->line);
        fputs($socket, $headers . $this->line);
        fputs($socket, $message . $this->line);
        fputs($socket, "." . $this->line); # this line sends a dot to mark the end of message
        if($this->parse_response($socket, 250, ".") != 250) { fclose($socket); return false; }
      }

      # say goodbye
      fputs($socket,"QUIT" . $this->line);
      $this->parse_response($socket, 221, "QUIT");
      fclose($socket);

      return true;
    }

    # parse server responces for above function
    function parse_response($socket, $expected, $cmd) {
      $response = '';
      $this->log[$cmd] = "";
      while (substr($response, 3, 1) != ' ') {
        if(!($response = fgets($socket, 256))) $this->log["ERROR RESPONSE"] = "Couldn't get mail server response codes.";
        else $this->log[$cmd] .= $response;
        # for security we break the loop after 10 cause this should not happen ever
        $i++;
        if($i == 10) return false;
      }

      # shows an error if expected code not received
      if(substr($response, 0, 3) != $expected) $this->log["ERROR CODES"] = "Ran into problems sending Mail. Received: " . substr($response, 0, 3) . ".. but expected: " . $expected;

      # access denied..quit
      if(substr($response, 0, 3) == 451) $this->log["ERROR QUIT"] = "Server declined access. Quitting.";

      return substr($response, 0, 3);
    }

    function find_mime($ext) {
      # create mimetypes array
      $mimetypes = $this->mime_array();

      # return mime type for extension
      if (isset($mimetypes[$ext])) {
        return $mimetypes[$ext];
      # if the extension wasn't found return octet-stream         
      } else {
        return 'application/octet-stream';
      }
    } 
    function mime_array() {
      return array(
        "ez" => "application/andrew-inset",
        "hqx" => "application/mac-binhex40",
        "cpt" => "application/mac-compactpro",
        "doc" => "application/msword",
        "bin" => "application/octet-stream",
        "dms" => "application/octet-stream",
        "lha" => "application/octet-stream",
        "lzh" => "application/octet-stream",
        "exe" => "application/octet-stream",
        "class" => "application/octet-stream",
        "so" => "application/octet-stream",
        "dll" => "application/octet-stream",
        "oda" => "application/oda",
        "pdf" => "application/pdf",
        "ai" => "application/postscript",
        "eps" => "application/postscript",
        "ps" => "application/postscript",
        "smi" => "application/smil",
        "smil" => "application/smil",
        "wbxml" => "application/vnd.wap.wbxml",
        "wmlc" => "application/vnd.wap.wmlc",
        "wmlsc" => "application/vnd.wap.wmlscriptc",
        "bcpio" => "application/x-bcpio",
        "vcd" => "application/x-cdlink",
        "pgn" => "application/x-chess-pgn",
        "cpio" => "application/x-cpio",
        "csh" => "application/x-csh",
        "dcr" => "application/x-director",
        "dir" => "application/x-director",
        "dxr" => "application/x-director",
        "dvi" => "application/x-dvi",
        "spl" => "application/x-futuresplash",
        "gtar" => "application/x-gtar",
        "hdf" => "application/x-hdf",
        "js" => "application/x-javascript",
        "skp" => "application/x-koan",
        "skd" => "application/x-koan",
        "skt" => "application/x-koan",
        "skm" => "application/x-koan",
        "latex" => "application/x-latex",
        "nc" => "application/x-netcdf",
        "cdf" => "application/x-netcdf",
        "sh" => "application/x-sh",
        "shar" => "application/x-shar",
        "swf" => "application/x-shockwave-flash",
        "sit" => "application/x-stuffit",
        "sv4cpio" => "application/x-sv4cpio",
        "sv4crc" => "application/x-sv4crc",
        "tar" => "application/x-tar",
        "tcl" => "application/x-tcl",
        "tex" => "application/x-tex",
        "texinfo" => "application/x-texinfo",
        "texi" => "application/x-texinfo",
        "t" => "application/x-troff",
        "tr" => "application/x-troff",
        "roff" => "application/x-troff",
        "man" => "application/x-troff-man",
        "me" => "application/x-troff-me",
        "ms" => "application/x-troff-ms",
        "ustar" => "application/x-ustar",
        "src" => "application/x-wais-source",
        "xhtml" => "application/xhtml+xml",
        "xht" => "application/xhtml+xml",
        "zip" => "application/zip",
        "au" => "audio/basic",
        "snd" => "audio/basic",
        "mid" => "audio/midi",
        "midi" => "audio/midi",
        "kar" => "audio/midi",
        "mpga" => "audio/mpeg",
        "mp2" => "audio/mpeg",
        "mp3" => "audio/mpeg",
        "aif" => "audio/x-aiff",
        "aiff" => "audio/x-aiff",
        "aifc" => "audio/x-aiff",
        "m3u" => "audio/x-mpegurl",
        "ram" => "audio/x-pn-realaudio",
        "rm" => "audio/x-pn-realaudio",
        "rpm" => "audio/x-pn-realaudio-plugin",
        "ra" => "audio/x-realaudio",
        "wav" => "audio/x-wav",
        "pdb" => "chemical/x-pdb",
        "xyz" => "chemical/x-xyz",
        "bmp" => "image/bmp",
        "gif" => "image/gif",
        "ief" => "image/ief",
        "jpeg" => "image/jpeg",
        "jpg" => "image/jpeg",
        "jpe" => "image/jpeg",
        "png" => "image/png",
        "tiff" => "image/tiff",
        "tif" => "image/tif",
        "djvu" => "image/vnd.djvu",
        "djv" => "image/vnd.djvu",
        "wbmp" => "image/vnd.wap.wbmp",
        "ras" => "image/x-cmu-raster",
        "pnm" => "image/x-portable-anymap",
        "pbm" => "image/x-portable-bitmap",
        "pgm" => "image/x-portable-graymap",
        "ppm" => "image/x-portable-pixmap",
        "rgb" => "image/x-rgb",
        "xbm" => "image/x-xbitmap",
        "xpm" => "image/x-xpixmap",
        "xwd" => "image/x-windowdump",
        "igs" => "model/iges",
        "iges" => "model/iges",
        "msh" => "model/mesh",
        "mesh" => "model/mesh",
        "silo" => "model/mesh",
        "wrl" => "model/vrml",
        "vrml" => "model/vrml",
        "css" => "text/css",
        "html" => "text/html",
        "htm" => "text/html",
        "asc" => "text/plain",
        "txt" => "text/plain",
        "rtx" => "text/richtext",
        "rtf" => "text/rtf",
        "sgml" => "text/sgml",
        "sgm" => "text/sgml",
        "tsv" => "text/tab-seperated-values",
        "wml" => "text/vnd.wap.wml",
        "wmls" => "text/vnd.wap.wmlscript",
        "etx" => "text/x-setext",
        "xml" => "text/xml",
        "xsl" => "text/xml",
        "mpeg" => "video/mpeg",
        "mpg" => "video/mpeg",
        "mpe" => "video/mpeg",
        "qt" => "video/quicktime",
        "mov" => "video/quicktime",
        "mxu" => "video/vnd.mpegurl",
        "avi" => "video/x-msvideo",
        "movie" => "video/x-sgi-movie",
        "ice" => "x-conference-xcooltalk"
      );
    } 
  }

  # PHP does not have getmxr function on windows so I built one
  function win_getmxrr($hostname, &$mxhosts, &$mxweight=false) {
    if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') return;
    if (!is_array ($mxhosts) ) $mxhosts = array();
    if (empty($hostname)) return;
    $exec='nslookup -type=MX '.escapeshellarg($hostname);
    @exec($exec, $output);
    if (empty($output)) return;
    $i=-1;
    foreach ($output as $line) {
      $i++;
      if (preg_match("/^$hostname\tMX preference = ([0-9]+), mail exchanger = (.+)$/i", $line, $parts)) {
        $mxweight[$i] = trim($parts[1]);
        $mxhosts[$i] = trim($parts[2]);
      }
      if (preg_match('/responsible mail addr = (.+)$/i', $line, $parts)) {
        $mxweight[$i] = $i;
        $mxhosts[$i] = trim($parts[1]);
      }
    }
    return ($i!=-1);
  }

  if (!function_exists('getmxrr')) {
    function getmxrr($hostname, &$mxhosts, &$mxweight=false) {
      return win_getmxrr($hostname, $mxhosts, $mxweight);
    }
  }

  function xmail($to, $subject, $message, $headers="", $attachments=""){
    $xmail = new Xmail();
    $xmail->setMODE("mx"); // default is mail; options: mail,smtp,mx

    // MX setup if in 'mx' mode
    $xmail->setFrom("someone@somedomain.com");
    $xmail->setHost($_SERVER['HTTP_HOST']);

    // SMTP SETUP if in 'smtp' mode
    $xmail->setSmtpHost("localhost");
    $xmail->setSmtpPort(25);
    $xmail->setSmtpUser("someuser");
    $xmail->setSmtpPass("somepassword");

    // from this point on you have to provide the same info as if you would use mail()
    if($headers == "")
     $headers = "From: <someone@somedomain.com>\r\n";

    // !!! DO NOT ADD MIME VERSION OR CONTENT TYPE HEADERS !!!

    // send the email
    $xmail->mail($to, $subject, $message, $headers, $attachments);
  }

?>

关于nginx - 无法从 Nginx php - 基于 fpm 的 dedi 发送电子邮件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12137426/

相关文章:

node.js - 在 Mongodb 中查询时出现速度问题和内存错误

php - 如何使用CSS将背景图像放在选择选项标签中

linux - mediatemple 内存使用率高达 105%

mysql - Plesk 备份还原后所有用户/数据库密码都已更改

amazon-ec2 - 专用服务器与 Amazon EC2

django - NGINX docker-compose - 在上游 nuxt :3000 中找不到主机

django - 使用 nginx 反向代理 + docker 设置避免 Google oauth 在从公共(public)服务器调用时重定向到本地主机

linux - 如何设置nginx最大打开文件数?

php - 将数据库条目添加在一起

php - 加密密码的安全方法