邮箱验证功能的实现
采用PHPMailer库实现了邮箱验证功能,下面请看代码
首先是发送邮件的函数
<?php include "class.phpmailer.php"; include "class.smtp.php"; function send_mail( $sendto_email, $subject, $body,$rec_name){ $mail = new PHPMailer(); $mail->isSMTP(); // send via SMTP $mail->Host = "mail.ustc.edu.cn"; // SMTP servers $mail->SMTPSecure = "ssl"; $mail->Port =465; $mail->SMTPAuth = true; // turn on SMTP authentication $mail->Username = "xxxx"; // SMTP username 注意:普通邮件认证不需要加 @域名 $mail->Password = "xxxx" ; // SMTP password $mail->setFrom("xxxx", "学海灯塔"); $mail->CharSet = "UTF-8"; // 这里指定字符集! $mail->addAddress($sendto_email,$rec_name); // 收件人邮箱和姓名 $mail->IsHTML(true); // send as HTML $mail->Subject = $subject; $mail->Body =$body; $mail->Form= "xxxx"; $mail->Helo= "xxxx"; $mail->Send(); ?>
这是一个名为send_mail的函数,用到了class.phpmailer.php与class.smtp.php两个库文件(文章末尾附上)
接着是注册表单
<form name="register" action="register_handle.php" method="post" class="login"> <p class="lead">注册用户</p> <div class="form-group"> <input type="text" autocomplete="off" class="required form-control" placeholder="用户名 *" name="username" value="<?php if(isset($_COOKIE["tuname"])){echo $_COOKIE["tuname"];}?>"> </div> <div class="form-group"> <input type="password" class="required form-control" placeholder="密码 *" name="password" value="<?php if(isset($_COOKIE["password"])){echo $_COOKIE["password"];}?>"> </div> <div class="form-group"> <input type="password" class="required form-control" placeholder="确认密码 *" name="ConformPassword" value="<?php if(isset($_COOKIE["password"])){echo $_COOKIE["password"];}?>"> </div> <div class="form-group"> <input type="text" autocomplete="off" class="required form-control" placeholder="科大邮箱 *" name="email" value="<?php if(isset($_COOKIE["email"])){echo $_COOKIE["email"];}?>"> <input type="submit" name="verification" value="发送验证码" class="course-submit" onclick="return check();"> </div> <div class="form-group"> <input type="text" autocomplete="off" class="required form-control" placeholder="邮箱验证码(登录邮箱查询) *" name="conformemail" value=""> </div> <div class="form-group"> <input type="submit" class="btn btn-primary btn-lg1 btn-block" name="submit" value="注册" > </div> </form>
注册信息处理
<?php include "mail.php"; function createRandomStr($length){ $str = "0123456789abcdefghijklmnopqrstuvwxyz"; $strlen = 0; while($length > $strlen){ $str .= $str; $strlen++; } $str = str_shuffle($str); return substr($str,0,$length); } $very=createRandomStr(6); $username=$_POST["username"]; $email=$_POST["email"]; $ac=0; $link = mysqli_connect("localhost","users","666","users"); if(isset($_POST["verification"])){ $password=$_POST["password"]; if(mysqli_query($link,"insert into users (username,password,mail,verycode,active) values("$username","$password","$email","$very","$ac")")) { send_mail($email, "欢迎使用学海灯塔!", "这是您的验证码:$very",$username); setcookie("password",$password,time()+7200); setcookie("tuname",$username,time()+7200); setcookie("email",$email,time()+7200); echo "<script>alert("验证码已发送");window.location.href= "register.php";</script>"; }else { echo "<script>alert("抱歉,该用户名已注册");window.location.href= "register.php";</script>"; } } if(isset($_POST["submit"])){ $veryin=$_POST["conformemail"]; $query=mysqli_query($link,"SELECT verycode FROM users WHERE username = "$username""); $row = mysqli_fetch_array($query); if($row["verycode"]==$veryin){ setcookie("uname",$username,time()+7200); setcookie("tuname","",time()-1); setcookie("password","",time()-1); setcookie("email","",time()-1); session_start(); $_SESSION[$username]=1; mysqli_query($link,"UPDATE users set active=1 WHERE username = "$username""); echo "<script>alert("验证成功");window.location= "index.php";</script>"; }else { echo "<script>alert("验证失败");history.go(-1)</script>"; } } ?>
其中createRandomStr用于生成随机验证码,接着调用send_mail进行发送。在服务器端的数据库中设置一个名为active的字段,当用户提交表单后进行验证码的比较,若正确则将其置为1,表示账号激活成功
附上两个库文件:
class.phpmailer.php:
<?php /*~ class.phpmailer.php .---------------------------------------------------------------------------. | Software: PHPMailer - PHP email class | | Version: 5.1 | | Contact: via sourceforge.net support pages (also www.worxware.com) | | Info: http://phpmailer.sourceforge.net | | Support: http://sourceforge.net/projects/phpmailer/ | | ------------------------------------------------------------------------- | | Admin: Andy Prevost (project admininistrator) | | Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net | | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net | | Founder: Brent R. Matzelle (original founder) | | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. | | Copyright (c) 2001-2003, Brent R. Matzelle | | ------------------------------------------------------------------------- | | License: Distributed under the Lesser General Public License (LGPL) | | http://www.gnu.org/copyleft/lesser.html | | This program is distributed in the hope that it will be useful - WITHOUT | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | | FITNESS FOR A PARTICULAR PURPOSE. | | ------------------------------------------------------------------------- | | We offer a number of paid services (www.worxware.com): | | - Web Hosting on highly optimized fast and secure servers | | - Technology Consulting | | - Oursourcing (highly qualified programmers and graphic designers) | "---------------------------------------------------------------------------" */ /** * PHPMailer - PHP email transport class * NOTE: Requires PHP version 5 or later * @package PHPMailer * @author Andy Prevost * @author Marcus Bointon * @copyright 2004 - 2009 Andy Prevost * @version $Id: class.phpmailer.php 447 2009-05-25 01:36:38Z codeworxtech $ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ if (version_compare(PHP_VERSION, "5.0.0", "<") ) exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater! "); class PHPMailer { ///////////////////////////////////////////////// // PROPERTIES, PUBLIC ///////////////////////////////////////////////// /** * Email priority (1 = High, 3 = Normal, 5 = low). * @var int */ public $Priority = 3; /** * Sets the CharSet of the message. * @var string */ public $CharSet = "iso-8859-1"; /** * Sets the Content-type of the message. * @var string */ public $ContentType = "text/plain"; /** * Sets the Encoding of the message. Options for this are * "8bit", "7bit", "binary", "base64", and "quoted-printable". * @var string */ public $Encoding = "8bit"; /** * Holds the most recent mailer error message. * @var string */ public $ErrorInfo = ""; /** * Sets the From email address for the message. * @var string */ public $From = "root@localhost"; /** * Sets the From name of the message. * @var string */ public $FromName = "Root User"; /** * Sets the Sender email (Return-Path) of the message. If not empty, * will be sent via -f to sendmail or as "MAIL FROM" in smtp mode. * @var string */ public $Sender = ""; /** * Sets the Subject of the message. * @var string */ public $Subject = ""; /** * Sets the Body of the message. This can be either an HTML or text body. * If HTML then run IsHTML(true). * @var string */ public $Body = ""; /** * Sets the text-only body of the message. This automatically sets the * email to multipart/alternative. This body can be read by mail * clients that do not have HTML email capability such as mutt. Clients * that can read HTML will view the normal Body. * @var string */ public $AltBody = ""; /** * Sets word wrapping on the body of the message to a given number of * characters. * @var int */ public $WordWrap = 0; /** * Method to send mail: ("mail", "sendmail", or "smtp"). * @var string */ public $Mailer = "mail"; /** * Sets the path of the sendmail program. * @var string */ public $Sendmail = "/usr/sbin/sendmail"; /** * Path to PHPMailer plugins. Useful if the SMTP class * is in a different directory than the PHP include path. * @var string */ public $PluginDir = ""; /** * Sets the email address that a reading confirmation will be sent. * @var string */ public $ConfirmReadingTo = ""; /** * Sets the hostname to use in Message-Id and Received headers * and as default HELO string. If empty, the value returned * by SERVER_NAME is used or "localhost.localdomain". * @var string */ public $Hostname = ""; /** * Sets the message ID to be used in the Message-Id header. * If empty, a unique id will be generated. * @var string */ public $MessageID = ""; ///////////////////////////////////////////////// // PROPERTIES FOR SMTP ///////////////////////////////////////////////// /** * Sets the SMTP hosts. All hosts must be separated by a * semicolon. You can also specify a different port * for each host by using this format: [hostname:port] * (e.g. "smtp1.example.com:25;smtp2.example.com"). * Hosts will be tried in order. * @var string */ public $Host = "localhost"; /** * Sets the default SMTP server port. * @var int */ public $Port = 25; /** * Sets the SMTP HELO of the message (Default is $Hostname). * @var string */ public $Helo = ""; /** * Sets connection prefix. * Options are "", "ssl" or "tls" * @var string */ public $SMTPSecure = ""; /** * Sets SMTP authentication. Utilizes the Username and Password variables. * @var bool */ public $SMTPAuth = false; /** * Sets SMTP username. * @var string */ public $Username = ""; /** * Sets SMTP password. * @var string */ public $Password = ""; /** * Sets the SMTP server timeout in seconds. * This function will not work with the win32 version. * @var int */ public $Timeout = 10; /** * Sets SMTP class debugging on or off. * @var bool */ public $SMTPDebug = false; /** * Prevents the SMTP connection from being closed after each mail * sending. If this is set to true then to close the connection * requires an explicit call to SmtpClose(). * @var bool */ public $SMTPKeepAlive = false; /** * Provides the ability to have the TO field process individual * emails, instead of sending to entire TO addresses * @var bool */ public $SingleTo = false; /** * If SingleTo is true, this provides the array to hold the email addresses * @var bool */ public $SingleToArray = array(); /** * Provides the ability to change the line ending * @var string */ public $LE = " "; /** * Used with DKIM DNS Resource Record * @var string */ public $DKIM_selector = "phpmailer"; /** * Used with DKIM DNS Resource Record * optional, in format of email address "you@yourdomain.com" * @var string */ public $DKIM_identity = ""; /** * Used with DKIM DNS Resource Record * optional, in format of email address "you@yourdomain.com" * @var string */ public $DKIM_domain = ""; /** * Used with DKIM DNS Resource Record * optional, in format of email address "you@yourdomain.com" * @var string */ public $DKIM_private = ""; /** * Callback Action function name * the function that handles the result of the send email action. Parameters: * bool $result result of the send action * string $to email address of the recipient * string $cc cc email addresses * string $bcc bcc email addresses * string $subject the subject * string $body the email body * @var string */ public $action_function = ""; //"callbackAction"; /** * Sets the PHPMailer Version number * @var string */ public $Version = "5.1"; ///////////////////////////////////////////////// // PROPERTIES, PRIVATE AND PROTECTED ///////////////////////////////////////////////// private $smtp = NULL; private $to = array(); private $cc = array(); private $bcc = array(); private $ReplyTo = array(); private $all_recipients = array(); private $attachment = array(); private $CustomHeader = array(); private $message_type = ""; private $boundary = array(); protected $language = array(); private $error_count = 0; private $sign_cert_file = ""; private $sign_key_file = ""; private $sign_key_pass = ""; private $exceptions = false; ///////////////////////////////////////////////// // CONSTANTS ///////////////////////////////////////////////// const STOP_MESSAGE = 0; // message only, continue processing const STOP_CONTINUE = 1; // message?, likely ok to continue processing const STOP_CRITICAL = 2; // message, plus full stop, critical error reached ///////////////////////////////////////////////// // METHODS, VARIABLES ///////////////////////////////////////////////// /** * Constructor * @param boolean $exceptions Should we throw external exceptions? */ public function __construct($exceptions = false) { $this->exceptions = ($exceptions == true); } /** * Sets message type to HTML. * @param bool $ishtml * @return void */ public function IsHTML($ishtml = true) { if ($ishtml) { $this->ContentType = "text/html"; } else { $this->ContentType = "text/plain"; } } /** * Sets Mailer to send message using SMTP. * @return void */ public function IsSMTP() { $this->Mailer = "smtp"; } /** * Sets Mailer to send message using PHP mail() function. * @return void */ public function IsMail() { $this->Mailer = "mail"; } /** * Sets Mailer to send message using the $Sendmail program. * @return void */ public function IsSendmail() { if (!stristr(ini_get("sendmail_path"), "sendmail")) { $this->Sendmail = "/var/qmail/bin/sendmail"; } $this->Mailer = "sendmail"; } /** * Sets Mailer to send message using the qmail MTA. * @return void */ public function IsQmail() { if (stristr(ini_get("sendmail_path"), "qmail")) { $this->Sendmail = "/var/qmail/bin/sendmail"; } $this->Mailer = "sendmail"; } ///////////////////////////////////////////////// // METHODS, RECIPIENTS ///////////////////////////////////////////////// /** * Adds a "To" address. * @param string $address * @param string $name * @return boolean true on success, false if address already used */ public function AddAddress($address, $name = "") { return $this->AddAnAddress("to", $address, $name); } /** * Adds a "Cc" address. * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer. * @param string $address * @param string $name * @return boolean true on success, false if address already used */ public function AddCC($address, $name = "") { return $this->AddAnAddress("cc", $address, $name); } /** * Adds a "Bcc" address. * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer. * @param string $address * @param string $name * @return boolean true on success, false if address already used */ public function AddBCC($address, $name = "") { return $this->AddAnAddress("bcc", $address, $name); } /** * Adds a "Reply-to" address. * @param string $address * @param string $name * @return boolean */ public function AddReplyTo($address, $name = "") { return $this->AddAnAddress("ReplyTo", $address, $name); } /** * Adds an address to one of the recipient arrays * Addresses that have been added already return false, but do not throw exceptions * @param string $kind One of "to", "cc", "bcc", "ReplyTo" * @param string $address The email address to send to * @param string $name * @return boolean true on success, false if address already used or invalid in some way * @access private */ private function AddAnAddress($kind, $address, $name = "") { if (!preg_match("/^(to|cc|bcc|ReplyTo)$/", $kind)) { echo "Invalid recipient array: " . kind; return false; } $address = trim($address); $name = trim(preg_replace("/[ ]+/", "", $name)); //Strip breaks and trim if (!self::ValidateAddress($address)) { $this->SetError($this->Lang("invalid_address").": ". $address); if ($this->exceptions) { throw new phpmailerException($this->Lang("invalid_address").": ".$address); } echo $this->Lang("invalid_address").": ".$address; return false; } if ($kind != "ReplyTo") { if (!isset($this->all_recipients[strtolower($address)])) { array_push($this->$kind, array($address, $name)); $this->all_recipients[strtolower($address)] = true; return true; } } else { if (!array_key_exists(strtolower($address), $this->ReplyTo)) { $this->ReplyTo[strtolower($address)] = array($address, $name); return true; } } return false; } /** * Set the From and FromName properties * @param string $address * @param string $name * @return boolean */ public function SetFrom($address, $name = "",$auto=1) { $address = trim($address); $name = trim(preg_replace("/[ ]+/", "", $name)); //Strip breaks and trim if (!self::ValidateAddress($address)) { $this->SetError($this->Lang("invalid_address").": ". $address); if ($this->exceptions) { throw new phpmailerException($this->Lang("invalid_address").": ".$address); } echo $this->Lang("invalid_address").": ".$address; return false; } $this->From = $address; $this->FromName = $name; if ($auto) { if (empty($this->ReplyTo)) { $this->AddAnAddress("ReplyTo", $address, $name); } if (empty($this->Sender)) { $this->Sender = $address; } } return true; } /** * Check that a string looks roughly like an email address should * Static so it can be used without instantiation * Tries to use PHP built-in validator in the filter extension (from PHP 5.2), falls back to a reasonably competent regex validator * Conforms approximately to RFC2822 * @link http://www.hexillion.com/samples/#Regex Original pattern found here * @param string $address The email address to check * @return boolean * @static * @access public */ public static function ValidateAddress($address) { if (function_exists("filter_var")) { //Introduced in PHP 5.2 if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) { return false; } else { return true; } } else { return preg_match("/^(?:[w!#$\%&"*+-/=?^`{|}~]+.)*[w!#$\%&"*+-/=?^`{|}~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_-](?!.)){0,61}[a-zA-Z0-9_-]?.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:[(?:(?:[01]?d{1,2}|2[0-4]d|25[0-5]).){3}(?:[01]?d{1,2}|2[0-4]d|25[0-5])]))$/", $address); } } ///////////////////////////////////////////////// // METHODS, MAIL SENDING ///////////////////////////////////////////////// /** * Creates message and assigns Mailer. If the message is * not sent successfully then it returns false. Use the ErrorInfo * variable to view description of the error. * @return bool */ public function Send() { try { if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { throw new phpmailerException($this->Lang("provide_address"), self::STOP_CRITICAL); } // Set whether the message is multipart/alternative if(!empty($this->AltBody)) { $this->ContentType = "multipart/alternative"; } $this->error_count = 0; // reset errors $this->SetMessageType(); $header = $this->CreateHeader(); $body = $this->CreateBody(); if (empty($this->Body)) { throw new phpmailerException($this->Lang("empty_message"), self::STOP_CRITICAL); } // digitally sign with DKIM if enabled if ($this->DKIM_domain && $this->DKIM_private) { $header_dkim = $this->DKIM_Add($header,$this->Subject,$body); $header = str_replace(" "," ",$header_dkim) . $header; } // Choose the mailer and send through it switch($this->Mailer) { case "sendmail": return $this->SendmailSend($header, $body); case "smtp": return $this->SmtpSend($header, $body); default: return $this->MailSend($header, $body); } } catch (phpmailerException $e) { $this->SetError($e->getMessage()); if ($this->exceptions) { throw $e; } echo $e->getMessage()." "; return false; } } /** * Sends mail using the $Sendmail program. * @param string $header The message headers * @param string $body The message body * @access protected * @return bool */ protected function SendmailSend($header, $body) { if ($this->Sender != "") { $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); } else { $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail)); } if ($this->SingleTo === true) { foreach ($this->SingleToArray as $key => $val) { if(!@$mail = popen($sendmail, "w")) { throw new phpmailerException($this->Lang("execute") . $this->Sendmail, self::STOP_CRITICAL); } fputs($mail, "To: " . $val . " "); fputs($mail, $header); fputs($mail, $body); $result = pclose($mail); // implement call back function if it exists $isSent = ($result == 0) ? 1 : 0; $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); if($result != 0) { throw new phpmailerException($this->Lang("execute") . $this->Sendmail, self::STOP_CRITICAL); } } } else { if(!@$mail = popen($sendmail, "w")) { throw new phpmailerException($this->Lang("execute") . $this->Sendmail, self::STOP_CRITICAL); } fputs($mail, $header); fputs($mail, $body); $result = pclose($mail); // implement call back function if it exists $isSent = ($result == 0) ? 1 : 0; $this->doCallback($isSent,$this->to,$this->cc,$this->bcc,$this->Subject,$body); if($result != 0) { throw new phpmailerException($this->Lang("execute") . $this->Sendmail, self::STOP_CRITICAL); } } return true; } /** * Sends mail using the PHP mail() function. * @param string $header The message headers * @param string $body The message body * @access protected * @return bool */ protected function MailSend($header, $body) { $toArr = array(); foreach($this->to as $t) { $toArr[] = $this->AddrFormat($t); } $to = implode(", ", $toArr); $params = sprintf("-oi -f %s", $this->Sender); if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1) { $old_from = ini_get("sendmail_from"); ini_set("sendmail_from", $this->Sender); if ($this->SingleTo === true && count($toArr) > 1) { foreach ($toArr as $key => $val) { $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); // implement call back function if it exists $isSent = ($rt == 1) ? 1 : 0; $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); } } else { $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); // implement call back function if it exists $isSent = ($rt == 1) ? 1 : 0; $this->doCallback($isSent,$to,$this->cc,$this->bcc,$this->Subject,$body); } } else { if ($this->SingleTo === true && count($toArr) > 1) { foreach ($toArr as $key => $val) { $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); // implement call back function if it exists $isSent = ($rt == 1) ? 1 : 0; $this->doCallback($isSent,$val,$this->cc,$this->bcc,$this->Subject,$body); } } else { $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header); // implement call back function if it exists $isSent = ($rt == 1) ? 1 : 0; $this->doCallback($isSent,$to,$this->cc,$this->bcc,$this->Subject,$body); } } if (isset($old_from)) { ini_set("sendmail_from", $old_from); } if(!$rt) { throw new phpmailerException($this->Lang("instantiate"), self::STOP_CRITICAL); } return true; } /** * Sends mail via SMTP using PhpSMTP * Returns false if there is a bad MAIL FROM, RCPT, or DATA input. * @param string $header The message headers * @param string $body The message body * @uses SMTP * @access protected * @return bool */ protected function SmtpSend($header, $body) { require_once $this->PluginDir . "class.smtp.php"; $bad_rcpt = array(); if(!$this->SmtpConnect()) { throw new phpmailerException($this->Lang("smtp_connect_failed"), self::STOP_CRITICAL); } $smtp_from = ($this->Sender == "") ? $this->From : $this->Sender; if(!$this->smtp->Mail($smtp_from)) { throw new phpmailerException($this->Lang("from_failed") . $smtp_from, self::STOP_CRITICAL); } // Attempt to send attach all recipients foreach($this->to as $to) { if (!$this->smtp->Recipient($to[0])) { $bad_rcpt[] = $to[0]; // implement call back function if it exists $isSent = 0; $this->doCallback($isSent,$to[0],"","",$this->Subject,$body); } else { // implement call back function if it exists $isSent = 1; $this->doCallback($isSent,$to[0],"","",$this->Subject,$body); } } foreach($this->cc as $cc) { if (!$this->smtp->Recipient($cc[0])) { $bad_rcpt[] = $cc[0]; // implement call back function if it exists $isSent = 0; $this->doCallback($isSent,"",$cc[0],"",$this->Subject,$body); } else { // implement call back function if it exists $isSent = 1; $this->doCallback($isSent,"",$cc[0],"",$this->Subject,$body); } } foreach($this->bcc as $bcc) { if (!$this->smtp->Recipient($bcc[0])) { $bad_rcpt[] = $bcc[0]; // implement call back function if it exists $isSent = 0; $this->doCallback($isSent,"","",$bcc[0],$this->Subject,$body); } else { // implement call back function if it exists $isSent = 1; $this->doCallback($isSent,"","",$bcc[0],$this->Subject,$body); } } if (count($bad_rcpt) > 0 ) { //Create error message for any bad addresses $badaddresses = implode(", ", $bad_rcpt); throw new phpmailerException($this->Lang("recipients_failed") . $badaddresses); } if(!$this->smtp->Data($header . $body)) { throw new phpmailerException($this->Lang("data_not_accepted"), self::STOP_CRITICAL); } if($this->SMTPKeepAlive == true) { $this->smtp->Reset(); } return true; } /** * Initiates a connection to an SMTP server. * Returns false if the operation failed. * @uses SMTP * @access public * @return bool */ public function SmtpConnect() { if(is_null($this->smtp)) { $this->smtp = new SMTP(); } $this->smtp->do_debug = $this->SMTPDebug; $hosts = explode(";", $this->Host); $index = 0; $connection = $this->smtp->Connected(); // Retry while there is no connection try { while($index < count($hosts) && !$connection) { $hostinfo = array(); if (preg_match("/^(.+):([0-9]+)$/", $hosts[$index], $hostinfo)) { $host = $hostinfo[1]; $port = $hostinfo[2]; } else { $host = $hosts[$index]; $port = $this->Port; } $tls = ($this->SMTPSecure == "tls"); $ssl = ($this->SMTPSecure == "ssl"); if ($this->smtp->Connect(($ssl ? "ssl://":"").$host, $port, $this->Timeout)) { $hello = ($this->Helo != "" ? $this->Helo : $this->ServerHostname()); $this->smtp->Hello($hello); if ($tls) { if (!$this->smtp->StartTLS()) { throw new phpmailerException($this->Lang("tls")); } //We must resend HELO after tls negotiation $this->smtp->Hello($hello); } $connection = true; if ($this->SMTPAuth) { if (!$this->smtp->Authenticate($this->Username, $this->Password)) { throw new phpmailerException($this->Lang("authenticate")); } } } $index++; if (!$connection) { throw new phpmailerException($this->Lang("connect_host")); } } } catch (phpmailerException $e) { $this->smtp->Reset(); throw $e; } return true; } /** * Closes the active SMTP session if one exists. * @return void */ public function SmtpClose() { if(!is_null($this->smtp)) { if($this->smtp->Connected()) { $this->smtp->Quit(); $this->smtp->Close(); } } } /** * Sets the language for all class error messages. * Returns false if it cannot load the language file. The default language is English. * @param string $langcode ISO 639-1 2-character language code (e.g. Portuguese: "br") * @param string $lang_path Path to the language file directory * @access public */ function SetLanguage($langcode = "en", $lang_path = "language/") { //Define full set of translatable strings $PHPMAILER_LANG = array( "provide_address" => "You must provide at least one recipient email address.", "mailer_not_supported" => " mailer is not supported.", "execute" => "Could not execute: ", "instantiate" => "Could not instantiate mail function.", "authenticate" => "SMTP Error: Could not authenticate.", "from_failed" => "The following From address failed: ", "recipients_failed" => "SMTP Error: The following recipients failed: ", "data_not_accepted" => "SMTP Error: Data not accepted.", "connect_host" => "SMTP Error: Could not connect to SMTP host.", "file_access" => "Could not access file: ", "file_open" => "File Error: Could not open file: ", "encoding" => "Unknown encoding: ", "signing" => "Signing Error: ", "smtp_error" => "SMTP server error: ", "empty_message" => "Message body empty", "invalid_address" => "Invalid address", "variable_set" => "Cannot set or reset variable: " ); //Overwrite language-specific strings. This way we"ll never have missing translations - no more "language string failed to load"! $l = true; if ($langcode != "en") { //There is no English translation file $l = @include $lang_path."phpmailer.lang-".$langcode.".php"; } $this->language = $PHPMAILER_LANG; return ($l == true); //Returns false if language not found } /** * Return the current array of language strings * @return array */ public function GetTranslations() { return $this->language; } ///////////////////////////////////////////////// // METHODS, MESSAGE CREATION ///////////////////////////////////////////////// /** * Creates recipient headers. * @access public * @return string */ public function AddrAppend($type, $addr) { $addr_str = $type . ": "; $addresses = array(); foreach ($addr as $a) { $addresses[] = $this->AddrFormat($a); } $addr_str .= implode(", ", $addresses); $addr_str .= $this->LE; return $addr_str; } /** * Formats an address correctly. * @access public * @return string */ public function AddrFormat($addr) { if (empty($addr[1])) { return $this->SecureHeader($addr[0]); } else { return $this->EncodeHeader($this->SecureHeader($addr[1]), "phrase") . " <" . $this->SecureHeader($addr[0]) . ">"; } } /** * Wraps message for use with mailers that do not * automatically perform wrapping and for quoted-printable. * Original written by philippe. * @param string $message The message to wrap * @param integer $length The line length to wrap to * @param boolean $qp_mode Whether to run in Quoted-Printable mode * @access public * @return string */ public function WrapText($message, $length, $qp_mode = false) { $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; // If utf-8 encoding is used, we will need to make sure we don"t // split multibyte characters when we wrap $is_utf8 = (strtolower($this->CharSet) == "utf-8"); $message = $this->FixEOL($message); if (substr($message, -1) == $this->LE) { $message = substr($message, 0, -1); } $line = explode($this->LE, $message); $message = ""; for ($i=0 ;$i < count($line); $i++) { $line_part = explode(" ", $line[$i]); $buf = ""; for ($e = 0; $e<count($line_part); $e++) { $word = $line_part[$e]; if ($qp_mode and (strlen($word) > $length)) { $space_left = $length - strlen($buf) - 1; if ($e != 0) { if ($space_left > 20) { $len = $space_left; if ($is_utf8) { $len = $this->UTF8CharBoundary($word, $len); } elseif (substr($word, $len - 1, 1) == "=") { $len--; } elseif (substr($word, $len - 2, 1) == "=") { $len -= 2; } $part = substr($word, 0, $len); $word = substr($word, $len); $buf .= " " . $part; $message .= $buf . sprintf("=%s", $this->LE); } else { $message .= $buf . $soft_break; } $buf = ""; } while (strlen($word) > 0) { $len = $length; if ($is_utf8) { $len = $this->UTF8CharBoundary($word, $len); } elseif (substr($word, $len - 1, 1) == "=") { $len--; } elseif (substr($word, $len - 2, 1) == "=") { $len -= 2; } $part = substr($word, 0, $len); $word = substr($word, $len); if (strlen($word) > 0) { $message .= $part . sprintf("=%s", $this->LE); } else { $buf = $part; } } } else { $buf_o = $buf; $buf .= ($e == 0) ? $word : (" " . $word); if (strlen($buf) > $length and $buf_o != "") { $message .= $buf_o . $soft_break; $buf = $word; } } } $message .= $buf . $this->LE; } return $message; } /** * Finds last character boundary prior to maxLength in a utf-8 * quoted (printable) encoded string. * Original written by Colin Brown. * @access public * @param string $encodedText utf-8 QP text * @param int $maxLength find last character boundary prior to this length * @return int */ public function UTF8CharBoundary($encodedText, $maxLength) { $foundSplitPos = false; $lookBack = 3; while (!$foundSplitPos) { $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); $encodedCharPos = strpos($lastChunk, "="); if ($encodedCharPos !== false) { // Found start of encoded character byte within $lookBack block. // Check the encoded byte value (the 2 chars after the "=") $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); $dec = hexdec($hex); if ($dec < 128) { // Single byte character. // If the encoded char was found at pos 0, it will fit // otherwise reduce maxLength to start of the encoded char $maxLength = ($encodedCharPos == 0) ? $maxLength : $maxLength - ($lookBack - $encodedCharPos); $foundSplitPos = true; } elseif ($dec >= 192) { // First byte of a multi byte character // Reduce maxLength to split at start of character $maxLength = $maxLength - ($lookBack - $encodedCharPos); $foundSplitPos = true; } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back $lookBack += 3; } } else { // No encoded character found $foundSplitPos = true; } } return $maxLength; } /** * Set the body wrapping. * @access public * @return void */ public function SetWordWrap() { if($this->WordWrap < 1) { return; } switch($this->message_type) { case "alt": case "alt_attachments": $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); break; default: $this->Body = $this->WrapText($this->Body, $this->WordWrap); break; } } /** * Assembles message header. * @access public * @return string The assembled header */ public function CreateHeader() { $result = ""; // Set the boundaries $uniq_id = md5(uniqid(time())); $this->boundary[1] = "b1_" . $uniq_id; $this->boundary[2] = "b2_" . $uniq_id; $result .= $this->HeaderLine("Date", self::RFCDate()); if($this->Sender == "") { $result .= $this->HeaderLine("Return-Path", trim($this->From)); } else { $result .= $this->HeaderLine("Return-Path", trim($this->Sender)); } // To be created automatically by mail() if($this->Mailer != "mail") { if ($this->SingleTo === true) { foreach($this->to as $t) { $this->SingleToArray[] = $this->AddrFormat($t); } } else { if(count($this->to) > 0) { $result .= $this->AddrAppend("To", $this->to); } elseif (count($this->cc) == 0) { $result .= $this->HeaderLine("To", "undisclosed-recipients:;"); } } } $from = array(); $from[0][0] = trim($this->From); $from[0][1] = $this->FromName; $result .= $this->AddrAppend("From", $from); // sendmail and mail() extract Cc from the header before sending if(count($this->cc) > 0) { $result .= $this->AddrAppend("Cc", $this->cc); } // sendmail and mail() extract Bcc from the header before sending if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0)) { $result .= $this->AddrAppend("Bcc", $this->bcc); } if(count($this->ReplyTo) > 0) { $result .= $this->AddrAppend("Reply-to", $this->ReplyTo); } // mail() sets the subject itself if($this->Mailer != "mail") { $result .= $this->HeaderLine("Subject", $this->EncodeHeader($this->SecureHeader($this->Subject))); } if($this->MessageID != "") { $result .= $this->HeaderLine("Message-ID",$this->MessageID); } else { $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); } $result .= $this->HeaderLine("X-Priority", $this->Priority); $result .= $this->HeaderLine("X-Mailer", "PHPMailer ".$this->Version." (phpmailer.sourceforge.net)"); if($this->ConfirmReadingTo != "") { $result .= $this->HeaderLine("Disposition-Notification-To", "<" . trim($this->ConfirmReadingTo) . ">"); } // Add custom headers for($index = 0; $index < count($this->CustomHeader); $index++) { $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); } if (!$this->sign_key_file) { $result .= $this->HeaderLine("MIME-Version", "1.0"); $result .= $this->GetMailMIME(); } return $result; } /** * Returns the message MIME. * @access public * @return string */ public function GetMailMIME() { $result = ""; switch($this->message_type) { case "plain": $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding); $result .= sprintf("Content-Type: %s; charset="%s"", $this->ContentType, $this->CharSet); break; case "attachments": case "alt_attachments": if($this->InlineImageExists()){ $result .= sprintf("Content-Type: %s;%s type="text/html";%s boundary="%s"%s", "multipart/related", $this->LE, $this->LE, $this->boundary[1], $this->LE); } else { $result .= $this->HeaderLine("Content-Type", "multipart/mixed;"); $result .= $this->TextLine(" boundary="" . $this->boundary[1] . """); } break; case "alt": $result .= $this->HeaderLine("Content-Type", "multipart/alternative;"); $result .= $this->TextLine(" boundary="" . $this->boundary[1] . """); break; } if($this->Mailer != "mail") { $result .= $this->LE.$this->LE; } return $result; } /** * Assembles the message body. Returns an empty string on failure. * @access public * @return string The assembled message body */ public function CreateBody() { $body = ""; if ($this->sign_key_file) { $body .= $this->GetMailMIME(); } $this->SetWordWrap(); switch($this->message_type) { case "alt": $body .= $this->GetBoundary($this->boundary[1], "", "text/plain", ""); $body .= $this->EncodeString($this->AltBody, $this->Encoding); $body .= $this->LE.$this->LE; $body .= $this->GetBoundary($this->boundary[1], "", "text/html", ""); $body .= $this->EncodeString($this->Body, $this->Encoding); $body .= $this->LE.$this->LE; $body .= $this->EndBoundary($this->boundary[1]); break; case "plain": $body .= $this->EncodeString($this->Body, $this->Encoding); break; case "attachments": $body .= $this->GetBoundary($this->boundary[1], "", "", ""); $body .= $this->EncodeString($this->Body, $this->Encoding); $body .= $this->LE; $body .= $this->AttachAll(); break; case "alt_attachments": $body .= sprintf("--%s%s", $this->boundary[1], $this->LE); $body .= sprintf("Content-Type: %s;%s" . " boundary="%s"%s", "multipart/alternative", $this->LE, $this->boundary[2], $this->LE.$this->LE); $body .= $this->GetBoundary($this->boundary[2], "", "text/plain", "") . $this->LE; // Create text body $body .= $this->EncodeString($this->AltBody, $this->Encoding); $body .= $this->LE.$this->LE; $body .= $this->GetBoundary($this->boundary[2], "", "text/html", "") . $this->LE; // Create the HTML body $body .= $this->EncodeString($this->Body, $this->Encoding); $body .= $this->LE.$this->LE; $body .= $this->EndBoundary($this->boundary[2]); $body .= $this->AttachAll(); break; } if ($this->IsError()) { $body = ""; } elseif ($this->sign_key_file) { try { $file = tempnam("", "mail"); file_put_contents($file, $body); //TODO check this worked $signed = tempnam("", "signed"); if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), NULL)) { @unlink($file); @unlink($signed); $body = file_get_contents($signed); } else { @unlink($file); @unlink($signed); throw new phpmailerException($this->Lang("signing").openssl_error_string()); } } catch (phpmailerException $e) { $body = ""; if ($this->exceptions) { throw $e; } } } return $body; } /** * Returns the start of a message boundary. * @access private */ private function GetBoundary($boundary, $charSet, $contentType, $encoding) { $result = ""; if($charSet == "") { $charSet = $this->CharSet; } if($contentType == "") { $contentType = $this->ContentType; } if($encoding == "") { $encoding = $this->Encoding; } $result .= $this->TextLine("--" . $boundary); $result .= sprintf("Content-Type: %s; charset = "%s"", $contentType, $charSet); $result .= $this->LE; $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding); $result .= $this->LE; return $result; } /** * Returns the end of a message boundary. * @access private */ private function EndBoundary($boundary) { return $this->LE . "--" . $boundary . "--" . $this->LE; } /** * Sets the message type. * @access private * @return void */ private function SetMessageType() { if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) { $this->message_type = "plain"; } else { if(count($this->attachment) > 0) { $this->message_type = "attachments"; } if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) { $this->message_type = "alt"; } if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) { $this->message_type = "alt_attachments"; } } } /** * Returns a formatted header line. * @access public * @return string */ public function HeaderLine($name, $value) { return $name . ": " . $value . $this->LE; } /** * Returns a formatted mail line. * @access public * @return string */ public function TextLine($value) { return $value . $this->LE; } ///////////////////////////////////////////////// // CLASS METHODS, ATTACHMENTS ///////////////////////////////////////////////// /** * Adds an attachment from a path on the filesystem. * Returns false if the file could not be found * or accessed. * @param string $path Path to the attachment. * @param string $name Overrides the attachment name. * @param string $encoding File encoding (see $Encoding). * @param string $type File extension (MIME) type. * @return bool */ public function AddAttachment($path, $name = "", $encoding = "base64", $type = "application/octet-stream") { try { if ( !@is_file($path) ) { throw new phpmailerException($this->Lang("file_access") . $path, self::STOP_CONTINUE); } $filename = basename($path); if ( $name == "" ) { $name = $filename; } $this->attachment[] = array( 0 => $path, 1 => $filename, 2 => $name, 3 => $encoding, 4 => $type, 5 => false, // isStringAttachment 6 => "attachment", 7 => 0 ); } catch (phpmailerException $e) { $this->SetError($e->getMessage()); if ($this->exceptions) { throw $e; } echo $e->getMessage()." "; if ( $e->getCode() == self::STOP_CRITICAL ) { return false; } } return true; } /** * Return the current array of attachments * @return array */ public function GetAttachments() { return $this->attachment; } /** * Attaches all fs, string, and binary attachments to the message. * Returns an empty string on failure. * @access private * @return string */ private function AttachAll() { // Return text of body $mime = array(); $cidUniq = array(); $incl = array(); // Add all attachments foreach ($this->attachment as $attachment) { // Check for string attachment $bString = $attachment[5]; if ($bString) { $string = $attachment[0]; } else { $path = $attachment[0]; } if (in_array($attachment[0], $incl)) { continue; } $filename = $attachment[1]; $name = $attachment[2]; $encoding = $attachment[3]; $type = $attachment[4]; $disposition = $attachment[6]; $cid = $attachment[7]; $incl[] = $attachment[0]; if ( $disposition == "inline" && isset($cidUniq[$cid]) ) { continue; } $cidUniq[$cid] = true; $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); $mime[] = sprintf("Content-Type: %s; name="%s"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE); $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); if($disposition == "inline") { $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); } $mime[] = sprintf("Content-Disposition: %s; filename="%s"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE); // Encode as string attachment if($bString) { $mime[] = $this->EncodeString($string, $encoding); if($this->IsError()) { return ""; } $mime[] = $this->LE.$this->LE; } else { $mime[] = $this->EncodeFile($path, $encoding); if($this->IsError()) { return ""; } $mime[] = $this->LE.$this->LE; } } $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); return join("", $mime); } /** * Encodes attachment in requested format. * Returns an empty string on failure. * @param string $path The full path to the file * @param string $encoding The encoding to use; one of "base64", "7bit", "8bit", "binary", "quoted-printable" * @see EncodeFile() * @access private * @return string */ private function EncodeFile($path, $encoding = "base64") { try { if (!is_readable($path)) { throw new phpmailerException($this->Lang("file_open") . $path, self::STOP_CONTINUE); } if (function_exists("get_magic_quotes")) { function get_magic_quotes() { return false; } } if (PHP_VERSION < 6) { $magic_quotes = get_magic_quotes_runtime(); set_magic_quotes_runtime(0); } $file_buffer = file_get_contents($path); $file_buffer = $this->EncodeString($file_buffer, $encoding); if (PHP_VERSION < 6) { set_magic_quotes_runtime($magic_quotes); } return $file_buffer; } catch (Exception $e) { $this->SetError($e->getMessage()); return ""; } } /** * Encodes string to requested format. * Returns an empty string on failure. * @param string $str The text to encode * @param string $encoding The encoding to use; one of "base64", "7bit", "8bit", "binary", "quoted-printable" * @access public * @return string */ public function EncodeString ($str, $encoding = "base64") { $encoded = ""; switch(strtolower($encoding)) { case "base64": $encoded = chunk_split(base64_encode($str), 76, $this->LE); break; case "7bit": case "8bit": $encoded = $this->FixEOL($str); //Make sure it ends with a line break if (substr($encoded, -(strlen($this->LE))) != $this->LE) $encoded .= $this->LE; break; case "binary": $encoded = $str; break; case "quoted-printable": $encoded = $this->EncodeQP($str); break; default: $this->SetError($this->Lang("encoding") . $encoding); break; } return $encoded; } /** * Encode a header string to best (shortest) of Q, B, quoted or none. * @access public * @return string */ public function EncodeHeader($str, $position = "text") { $x = 0; switch (strtolower($position)) { case "phrase": if (!preg_match("/[200-377]/", $str)) { // Can"t use addslashes as we don"t know what value has magic_quotes_sybase $encoded = addcslashes($str, " ..37177\""); if (($str == $encoded) && !preg_match("/[^A-Za-z0-9!#$%&"*+/=?^_`{|}~ -]/", $str)) { return ($encoded); } else { return (""$encoded""); } } $x = preg_match_all("/[^ 40 41 43-133135-176]/", $str, $matches); break; case "comment": $x = preg_match_all("/[()"]/", $str, $matches); // Fall-through case "text": default: $x += preg_match_all("/[ 00- 10 13 14 16- 37177-377]/", $str, $matches); break; } if ($x == 0) { return ($str); } $maxlen = 75 - 7 - strlen($this->CharSet); // Try to select the encoding which should produce the shortest output if (strlen($str)/3 < $x) { $encoding = "B"; if (function_exists("mb_strlen") && $this->HasMultiBytes($str)) { // Use a custom function which correctly encodes and wraps long // multibyte strings without breaking lines within a character $encoded = $this->Base64EncodeWrapMB($str); } else { $encoded = base64_encode($str); $maxlen -= $maxlen % 4; $encoded = trim(chunk_split($encoded, $maxlen, " ")); } } else { $encoding = "Q"; $encoded = $this->EncodeQ($str, $position); $encoded = $this->WrapText($encoded, $maxlen, true); $encoded = str_replace("=".$this->LE, " ", trim($encoded)); } $encoded = preg_replace("/^(.*)$/m", " =?".$this->CharSet."?$encoding?\1?=", $encoded); $encoded = trim(str_replace(" ", $this->LE, $encoded)); return $encoded; } /** * Checks if a string contains multibyte characters. * @access public * @param string $str multi-byte text to wrap encode * @return bool */ public function HasMultiBytes($str) { if (function_exists("mb_strlen")) { return (strlen($str) > mb_strlen($str, $this->CharSet)); } else { // Assume no multibytes (we can"t handle without mbstring functions anyway) return false; } } /** * Correctly encodes and wraps long multibyte strings for mail headers * without breaking lines within a character. * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php * @access public * @param string $str multi-byte text to wrap encode * @return string */ public function Base64EncodeWrapMB($str) { $start = "=?".$this->CharSet."?B?"; $end = "?="; $encoded = ""; $mb_length = mb_strlen($str, $this->CharSet); // Each line must have length <= 75, including $start and $end $length = 75 - strlen($start) - strlen($end); // Average multi-byte ratio $ratio = $mb_length / strlen($str); // Base64 has a 4:3 ratio $offset = $avgLength = floor($length * $ratio * .75); for ($i = 0; $i < $mb_length; $i += $offset) { $lookBack = 0; do { $offset = $avgLength - $lookBack; $chunk = mb_substr($str, $i, $offset, $this->CharSet); $chunk = base64_encode($chunk); $lookBack++; } while (strlen($chunk) > $length); $encoded .= $chunk . $this->LE; } // Chomp the last linefeed $encoded = substr($encoded, 0, -strlen($this->LE)); return $encoded; } /** * Encode string to quoted-printable. * Only uses standard PHP, slow, but will always work * @access public * @param string $string the text to encode * @param integer $line_max Number of chars allowed on a line before wrapping * @return string */ public function EncodeQPphp( $input = "", $line_max = 76, $space_conv = false) { $hex = array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"); $lines = preg_split("/(?: | | )/", $input); $eol = " "; $escape = "="; $output = ""; while( list(, $line) = each($lines) ) { $linlen = strlen($line); $newline = ""; for($i = 0; $i < $linlen; $i++) { $c = substr( $line, $i, 1 ); $dec = ord( $c ); if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E $c = "=2E"; } if ( $dec == 32 ) { if ( $i == ( $linlen - 1 ) ) { // convert space at eol only $c = "=20"; } else if ( $space_conv ) { $c = "=20"; } } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode " ", which is *not* required $h2 = floor($dec/16); $h1 = floor($dec%16); $c = $escape.$hex[$h2].$hex[$h1]; } if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted $output .= $newline.$escape.$eol; // soft line break; " = " is okay $newline = ""; // check if newline first character will be point or not if ( $dec == 46 ) { $c = "=2E"; } } $newline .= $c; } // end of for $output .= $newline.$eol; } // end of while return $output; } /** * Encode string to RFC2045 (6.7) quoted-printable format * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version * Also results in same content as you started with after decoding * @see EncodeQPphp() * @access public * @param string $string the text to encode * @param integer $line_max Number of chars allowed on a line before wrapping * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function * @return string * @author Marcus Bointon */ public function EncodeQP($string, $line_max = 76, $space_conv = false) { if (function_exists("quoted_printable_encode")) { //Use native function if it"s available (>= PHP5.3) return quoted_printable_encode($string); } $filters = stream_get_filters(); if (!in_array("convert.*", $filters)) { //Got convert stream filter? return $this->EncodeQPphp($string, $line_max, $space_conv); //Fall back to old implementation } $fp = fopen("php://temp/", "r+"); $string = preg_replace("/ ?/", $this->LE, $string); //Normalise line breaks $params = array("line-length" => $line_max, "line-break-chars" => $this->LE); $s = stream_filter_append($fp, "convert.quoted-printable-encode", STREAM_FILTER_READ, $params); fputs($fp, $string); rewind($fp); $out = stream_get_contents($fp); stream_filter_remove($s); $out = preg_replace("/^./m", "=2E", $out); //Encode . if it is first char on a line, workaround for bug in Exchange fclose($fp); return $out; } /** * Encode string to q encoding. * @link http://tools.ietf.org/html/rfc2047 * @param string $str the text to encode * @param string $position Where the text is going to be used, see the RFC for what that means * @access public * @return string */ public function EncodeQ ($str, $position = "text") { // There should not be any EOL in the string $encoded = preg_replace("/[ ]*/", "", $str); switch (strtolower($position)) { case "phrase": $encoded = preg_replace("/([^A-Za-z0-9!*+/ -])/e", ""=".sprintf("%02X", ord("\1"))", $encoded); break; case "comment": $encoded = preg_replace("/([()"])/e", ""=".sprintf("%02X", ord("\1"))", $encoded); case "text": default: // Replace every high ascii, control =, ? and _ characters //TODO using /e (equivalent to eval()) is probably not a good idea $encoded = preg_replace("/([ 00- 11 13 14 16- 37 75 77137177-377])/e", ""=".sprintf("%02X", ord("\1"))", $encoded); break; } // Replace every spaces to _ (more readable than =20) $encoded = str_replace(" ", "_", $encoded); return $encoded; } /** * Adds a string or binary attachment (non-filesystem) to the list. * This method can be used to attach ascii or binary data, * such as a BLOB record from a database. * @param string $string String attachment data. * @param string $filename Name of the attachment. * @param string $encoding File encoding (see $Encoding). * @param string $type File extension (MIME) type. * @return void */ public function AddStringAttachment($string, $filename, $encoding = "base64", $type = "application/octet-stream") { // Append to $attachment array $this->attachment[] = array( 0 => $string, 1 => $filename, 2 => basename($filename), 3 => $encoding, 4 => $type, 5 => true, // isStringAttachment 6 => "attachment", 7 => 0 ); } /** * Adds an embedded attachment. This can include images, sounds, and * just about any other document. Make sure to set the $type to an * image type. For JPEG images use "image/jpeg" and for GIF images * use "image/gif". * @param string $path Path to the attachment. * @param string $cid Content ID of the attachment. Use this to identify * the Id for accessing the image in an HTML form. * @param string $name Overrides the attachment name. * @param string $encoding File encoding (see $Encoding). * @param string $type File extension (MIME) type. * @return bool */ public function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", $type = "application/octet-stream") { if ( !@is_file($path) ) { $this->SetError($this->Lang("file_access") . $path); return false; } $filename = basename($path);
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: 如何android 的数组去接收用户输入的数据?
- 下一篇: PHP中读写文件+实现代码