PHP应用程序的空白邮件

时间:2010-05-23 08:06:49

标签: php email

问题:来自PHP Web应用程序的空白电子邮件。

确认:App在Linux中运行,在Windows服务器环境中存在各种问题。空白电子邮件是最后一个问题。

服务器上的PHP 5.2.6版

我是一名图书管理员,实施基于PHP的Web应用程序,以帮助学生完成他们的作业。我之前在基于Linux的免费网络主机上安装了此应用程序并且没有任何问题。

电子邮件由两个文件控制,即email_functions.php和email.php。虽然可以发送电子邮件,但发送的所有内容都是空白电子邮件。

我的IT部门是一家仅限ASP的商店,因此我几乎没有任何帮助。我也无法安装其他库,如PHPmail或Swiftmailer。

您可以在http://rpc.elm4you.org/查看功能副本。您也可以从Sourceforge的链接下载副本。

提前感谢您对此有任何见解!

email_functions.php

<?php
/**********************************************************
Function: build_multipart_headers
***********************************************************
Purpose:
Creates email headers for a message of type multipart/mime
This will include a plain text part and HTML.
**********************************************************/ 
function build_multipart_headers($boundary_rand)
{
 global $EMAIL_FROM_DISPLAY_NAME, $EMAIL_FROM_ADDRESS, $CALC_PATH, $CALC_TITLE, $SERVER_NAME;
 // Using \n instead of \r\n because qmail doubles up the \r and screws everything up!
 $crlf = "\n";
 $message_date = date("r");

 // Construct headers for multipart/mixed MIME email.  It will have a plain text and HTML part
 $headers = "X-Calc-Name: $CALC_TITLE" . $crlf;
 $headers .= "X-Calc-Url: http://{$SERVER_NAME}/{$CALC_PATH}" . $crlf;
 $headers .= "MIME-Version: 1.0" . $crlf;
 $headers .= "Content-type: multipart/alternative;" . $crlf;
 $headers .= "   boundary=__$boundary_rand" . $crlf;
 $headers .= "From: $EMAIL_FROM_DISPLAY_NAME <$EMAIL_FROM_ADDRESS>" . $crlf;
 $headers .= "Sender: $EMAIL_FROM_DISPLAY_NAME <$EMAIL_FROM_ADDRESS>" . $crlf;
 $headers .= "Reply-to: $EMAIL_FROM_DISPLAY_NAME <$EMAIL_FROM_ADDRESS>" . $crlf;
 $headers .= "Return-Path: $EMAIL_FROM_DISPLAY_NAME <$EMAIL_FROM_ADDRESS>" . $crlf;
 $headers .= "Date: $message_date" . $crlf;
 $headers .= "Message-Id: $boundary_rand@$SERVER_NAME" . $crlf;

 return $headers;
}
/**********************************************************
Function: build_multipart_body
***********************************************************
Purpose:
Builds the email body content to go with the headers from
build_multipart_headers()
**********************************************************/ 
function build_multipart_body($plain_text_message, $html_message, $boundary_rand)
{
 //$crlf = "\r\n";
 $crlf = "\n";
 $boundary = "__" . $boundary_rand;

 // Begin constructing the MIME multipart message
 $multipart_message = "This is a multipart message in MIME format." . $crlf . $crlf;
 $multipart_message .= "--{$boundary}{$crlf}Content-type: text/plain; charset=\"us-ascii\"{$crlf}Content-Transfer-Encoding: 7bit{$crlf}{$crlf}";
 $multipart_message .= $plain_text_message . $crlf . $crlf;
 $multipart_message .= "--{$boundary}{$crlf}Content-type: text/html; charset=\"iso-8859-1\"{$crlf}Content-Transfer-Encoding: 7bit{$crlf}{$crlf}";
 $multipart_message .= $html_message . $crlf . $crlf;
 $multipart_message .= "--{$boundary}--$crlf$crlf";

 return $multipart_message;
}
/**********************************************************
Function: build_step_email_body_text
***********************************************************
Purpose:
Returns a plain text version of the email body to be used
for individually sent step reminders
**********************************************************/ 
function build_step_email_body_text($stepnum, $arr_instructions, $dates, $query_string, $teacher_info ,$name, $class, $project_id)
{
 global $CALC_PATH, $CALC_TITLE, $SERVER_NAME;

 $step_email_body =<<<BODY

$CALC_TITLE
Step $stepnum: {$arr_instructions["step$stepnum"]["title"]}

Name: $name
Class: $class

BODY;

 $step_email_body .= build_text_single_step($stepnum, $arr_instructions, $dates, $query_string, $teacher_info);
 $step_email_body .= "\n\n"; 
 $step_email_body .=<<<FOOTER
The $CALC_TITLE offers suggestions, but be sure to check with your teacher to find out the best working schedule for your assignment! 

If you would like to stop receiving further reminders for this project, click the link below:
http://$SERVER_NAME/$CALC_PATH/deleteproject.php?proj=$project_id

FOOTER;
 // Wrap text to 78 chars per line
 // Convert any remaining HTML <br /> to \r\n
 // Strip out any remaining HTML tags.
 $step_email_body = strip_tags(linebreaks_html2text(wordwrap($step_email_body, 78, "\n")));
 return $step_email_body;
}
/**********************************************************
Function: build_step_email_body_html
***********************************************************
Purpose:
Same as above, but with HTML
**********************************************************/ 
function build_step_email_body_html($stepnum, $arr_instructions, $dates, $query_string, $teacher_info, $name, $class, $project_id)
{
 global $CALC_PATH, $CALC_TITLE, $SERVER_NAME;
 $styles = build_html_styles();
 $step_email_body =<<<BODY
<html>
<head>
 <title> $CALC_TITLE </title>
 $styles
</head>
<body>
<h1> $CALC_TITLE Schedule </h1>
<strong>Name:</strong>  $name <br />
<strong>Class:</strong> $class <br />

BODY;

 $step_email_body .= build_html_single_step($stepnum, $arr_instructions, $dates, $query_string, $teacher_info);

 $step_email_body .=<<<FOOTER
<p>
 The $CALC_TITLE offers suggestions, but be sure to check with your teacher to find out the best working schedule for your assignment!
</p>
<p>
 If you would like to stop receiving further reminders for this project, 
 <a href="http://{$SERVER_NAME}/$CALC_PATH/deleteproject.php?proj=$project_id">click this link.</a>
</p>
</body>
</html>

FOOTER;
 return $step_email_body;
}

/**********************************************************
Function: build_html_styles
***********************************************************
Purpose:
Just returns a string of <style /> for the HTML message body
**********************************************************/ 
function build_html_styles()
{
 $styles =<<<STYLES
 <style type="text/css">
  body { font-family: Arial, sans-serif; font-size: 85%; }
  h1 { font-size: 120%; }
  table { border: none; }
  tr { vertical-align: top; }
  img { display: none; }
  hr { border: 0; }
 </style>

STYLES;
 return $styles;
}

/**********************************************************
Function: linebreaks_html2text
***********************************************************
Purpose:
Convert <br /> html tags to \n line breaks
**********************************************************/ 
function linebreaks_html2text($in_string)
{
 $out_string = "";
 $arr_br = array("<br>", "<br />", "<br/>");
 $out_string = str_replace($arr_br, "\n", $in_string);
 return $out_string;
}

?>

email.php

<?php
require_once("include/config.php");
require_once("include/instructions.php");
require_once("dbase/dbfunctions.php");
require_once("include/email_functions.php");
ini_set("sendmail_from", "reference@cna-qatar.edu.qa");
ini_set("SMTP", "mail.qatar.net.qa");

// Verify that the email has not already been sent by checking for a cookie
// whose value is generated each time the form is loaded freshly.
if (!(isset($_COOKIE['rpc_transid']) && $_COOKIE['rpc_transid'] == $_POST['transid']))
{
 // Setup some preliminary variables for email.
 // The scanning of $_POST['email']already took place when this file was included...
 $to      = $_POST['email'];
 $subject = $EMAIL_SUBJECT;
 $boundary_rand = md5(rand());
 $mail_type = "";

 switch ($_POST['reminder-type'])
 {
  case "progressive":
   $arr_dbase_dates = array();
   $conn = rpc_connect();

   if (!$conn) 
   {
    $mail_success = FALSE;
    $mail_status_message = "Could not register address!";
    break;
   }
   // Sanitize all the data that will be inserted into table...
   // We need to remove "CONTENT-TYPE:" from name/class to defang them.
   // Additionall, we can't allow any line-breaks in those fields to avoid
   // hacks to email headers.
   $ins_name = mysql_real_escape_string($name);
   $ins_name = eregi_replace("CONTENT-TYPE", "...Content_Type...", $ins_name);
   $ins_name = str_replace("\n", "", $ins_name);
   $ins_class = mysql_real_escape_string($class);
   $ins_class = eregi_replace("CONTENT-TYPE", "...Content_Type...", $ins_class);
   $ins_class = str_replace("\n", "", $ins_class);
   $ins_email = mysql_real_escape_string($email);
   $ins_teacher_info = $teacher_info ? "YES" : "NO";

   switch ($format)
   {
    case "Slides": $ins_format = "SLIDES"; break;
    case "Video": $ins_format = "VIDEO"; break;
    case "Essay": 
    default: $ins_format = "ESSAY"; break;
   }

   // The transid from the previous form will be used as a project identifier
   // Steps will be grouped by project identifier.
   $ins_project_id = mysql_real_escape_string($_POST['transid'] . md5(rand()));
   $arr_dbase_dates = dbase_dates($dates);
   $arr_past_dates = array();

   // Iterate over the dates array and build a SQL statement for each one.
   $insert_success = TRUE;

   //
   $min_reminder_date = date("Ymd",  mktime(0,0,0,date("m"),date("d")+$EMAIL_REMINDER_DAYS_AHEAD,date("Y")));
   for ($date_index = 0; $date_index < sizeof($arr_dbase_dates); $date_index++)
   {
    // Make sure we're using the right keys...
    $ins_date_index  = $date_index + 1;

    // The insert will only happen if the date of the event is in the future.
    // For dates today and earlier, no insert.
    // For dates today or after the reminder deadline, we'll send the email immediately after the inserts.
    if ($arr_dbase_dates[$date_index] > (int)$min_reminder_date)
    { 
     $qry =<<<QRY
      INSERT INTO email_queue
      (
       NOTIFICATION_ID,
       PROJECT_ID,
       EMAIL,
       NAME,
       CLASS,
       FORMAT,
       TEACHER_INFO,
       STEP,
       MESSAGE_DATE
      )
      VALUES (
       NULL,
       '$ins_project_id',
       '$ins_email',
       '$ins_name',
       '$ins_class',
       '$ins_format',
       '$ins_teacher_info',
       $ins_date_index, /*step number*/
       {$arr_dbase_dates[$date_index]} /* Date in the integer format yyyymmdd */
      )
QRY;

     // Attempt to do the insert...
     $result = mysql_query($qry);

     // If even one insert fails, bail out.
     if (!$result)
     {
      $mail_success = FALSE;
      $mail_status_message = "Could not register address!";
      break;
     }
    }
    // For dates today or earlier, store the steps=>dates in an array so the mails can
    // be sent immediately.
    else
    {
     $arr_past_dates[$ins_date_index] = $arr_dbase_dates[$date_index];
    }
   }
   // Close the connection resources.
   mysql_close($conn);

   // SEND OUT THE EMAILS THAT HAVE TO GO IMMEDIATELY...
   // This should only be step 1, but who knows...
   //var_dump($arr_past_dates);
   for ($stepnum=1; $stepnum<=sizeof($arr_past_dates); $stepnum++)
   {

    $email_teacher_info = ($teacher_info && $EMAIL_TEACHER_REMINDERS) ? TRUE : FALSE;
    $boundary = md5(rand());
    $plain_text_body = build_step_email_body_text($stepnum, $arr_instructions, $dates, $query_string, $email_teacher_info ,$name, $class, $ins_project_id);
    $html_body = build_step_email_body_html($stepnum, $arr_instructions, $dates, $query_string, $email_teacher_info ,$name, $class, $ins_project_id);
    $multipart_headers = build_multipart_headers($boundary);
    $multipart_body = build_multipart_body($plain_text_body, $html_body, $boundary);
    mail($to, $subject . ": Step " . $stepnum, $multipart_body, $multipart_headers, "-fresearch@rpc.elm4you.org");
   }

   // Set appropriate flags and messages
   $mail_success = TRUE;
   $mail_status_message = "Email address registered!";
   $mail_type = "progressive";
   set_mail_success_cookie();
   break;

  // Default to a single email message.
  case "single":
  default:
   // We don't want to send images in the message, so strip them out of the existing structure.
   // This big ugly regex strips the whole table cell containing the image out of the table.
   // Must find a better solution...
   //$email_table_html = eregi_replace("<td class=\"stepImageContainer\" width=\"161px\">[\s\r\n\t]*<img class=\"stepImage\" src=\"images/[_a-zA-Z0-9]*\.gif\" alt=\"Step [1-9]{1} logo\" />[\s\r\n\t]*</td>", "\n", $table_html);
   // Show more descriptive text based on the value of $format
   switch ($format)
   {
    case "Video": $format_display = "Video"; break;
    case "Slides": $format_display = "Presentation with electronic slides"; break;
    case "Essay": 
    default:
     $format_display = "Essay"; break;
   }
   $days = (int)$days;

   $html_message = "";
   $styles = build_html_styles();
   $html_message =<<<HTMLMESSAGE
<html>
<head>
 <title> $CALC_TITLE </title>
 $styles
</head>
<body>
 <h1> $CALC_TITLE Schedule </h1>
 <strong>Name:</strong>  $name <br />
 <strong>Class:</strong> $class <br />
 <strong>Email:</strong> $email <br />
 <strong>Assignment type:</strong> $format_display <br /><br />
 <strong>Starting on:</strong> $date1 <br />
 <strong>Assignment due:</strong> $date2 <br />
 <strong>You have $days days to finish.</strong><br />
 <hr />

 $email_table_html
</body>
</html>
HTMLMESSAGE;

   // Create the plain text version of the message...
   $plain_text_message = strip_tags(linebreaks_html2text(build_text_all_steps($arr_instructions, $dates, $query_string, $teacher_info)));
   //  Add the title, since it doesn't get built in by build_text_all_steps...
   $plain_text_message = $CALC_TITLE . " Schedule\n\n" . $plain_text_message;
   $plain_text_message = wordwrap($plain_text_message, 78, "\n");
   $multipart_headers = build_multipart_headers($boundary_rand);
   $multipart_message = build_multipart_body($plain_text_message, $html_message, $boundary_rand);

   $mail_success = FALSE;
   if (mail($to, $subject, $multipart_message, $multipart_headers, "-reference@cna-qatar.edu.qa"))
   {
    $mail_success = TRUE;
    $mail_status_message = "Email sent!";
    $mail_type = "single";
    set_mail_success_cookie();
   }
   else
   {
    $mail_success = FALSE;
    $mail_status_message = "Could not send email!";
   }
  break;
 }
}

function set_mail_success_cookie()
{
 // Prevent the mail from being resent on page reload. Set a timestamp cookie.
 // Expires in 24 hours.
 setcookie("rpc_transid", $_POST['transid'], time() + 86400);
}

?>

2 个答案:

答案 0 :(得分:0)

不是发送它,而是构建电子邮件并显示邮件调用中使用的所有变量到屏幕并注释掉邮件调用。这将证实变量正在构建中。

然后再次开始使用邮件功能,如果您有权访问有用的邮件日志,因为它可能会为您提供更多信息。此外,请查看您收到的电子邮件中的标题,因为这也可能会显示标题或2已搞砸。

还可以尝试设置$crlf = "\r\n";

答案 1 :(得分:0)

Brett,如果你认为它是标题,我会尝试最低限度并让它发挥作用。一旦它工作,开始添加标题,直到你得到错误。然后告诉我们问题所在。