<?php 
  
    /**这个是改自pear中的解码类,增加了多种解码方式,修正了源码的系列bug.将解出的邮件分正文和附件存储,提高了解码效率。 
    * Mime decode class 
    * 
    * this class used at undecode Mime Files 
    * useage: 
    * 
    *    $message=GetMessage($filename,$read_type,$read_size);     
    *    $structure=RdMail($message); 
    *    $from=$structure->headers['from']; 
    *    $to=$structure->headers['to']; 
    * 
    * @copyright (c) 2004, richard,bjcctv. All rights reserved. 
    * @author richard,bjcctv 
    * @date:2004-11-24 last modified at:2005-06-01 
    * @package MimeDecode 
    * @version $Id$ 
    */ 
  
class Decode_Mimemail 

  
    /** 
     * Mime File 
     * @var    string 
     */ 
    var $_input; 
  
    /** 
     * header string 
     * @var    string 
     */ 
    var $_header; 
  
    /** 
     * body string 
     * @var    string 
     */ 
    var $_body; 
  
    /** 
     * err info 
     * @var    string 
     */ 
    var $_error; 
  
    /** 
     * whether include body object 
     * @var    boolean 
     */ 
    var $_include_bodies; 
  
    /** 
     * whether include body object 
     * @var    boolean 
     */ 
    var $_decode_bodies; 
  
    /** 
     * whether decode headers object 
     * @var    boolean 
     */ 
    var $_decode_headers; 
  
    /** 
     * crlf variable 
     * @var    string 
     */ 
    var $_crlf; 
  
    /** 
     * body parts 
     * @var object 
     */ 
    var $parts; 
    var $mid; 
    var $maildir; 
  
    /** 
     * Constructor. 
     * 
     * Sets up the object, initialise the variables, and splits and 
     * stores the header and body of the input. 
     * 
     * @param string The input to decode 
     * @access public 
     */ 
      
    function Decode_Mimemail($input, $mid, $maildir, $crlf = "\n") 
    { 
        $this->_crlf   = "\n"; 
        list($header, $body)    = $this->splitBodyHeader($input); //拆分信头和信体两块 
        $this->_input            = $input; 
        $this->_header            = $header; 
        $this->_body            = $body; 
        $this->mid                = $mid; 
        $this->maildir            = $maildir; 
        $this->_decode_bodies    = false; 
        $this->_include_bodies    = true; 
    } 
  
    /** 
     * Begins the decoding process. If called statically 
     * it will create an object and call the decode() method 
     * of it. 
     * 
     * @param array An array of various parameters that determine 
     *              various things: 
     *              include_bodies - Whether to include the body in the returned 
     *                               object. 
     *              decode_bodies  - Whether to decode the bodies 
     *                               of the parts. (Transfer encoding) 
     *              decode_headers - Whether to decode headers 
     *              input          - If called statically, this will be treated 
     *                               as the input 
     * @return object Decoded results 
     * @access public 
     */ 
     
    function decode($params = null) 
    { 
        // Have we been called statically? 
        // If so, create an object and pass details to that. 
        if (!isset($this) AND isset($params['input'])) 
        { 
            if (isset($params['crlf'])) 
            { 
                $obj = new Decode_Mimemail($params['input'],$params['mid'],$params['maildir'],$params['crlf']); 
            } 
            else 
            { 
                $obj = new Decode_Mimemail($params['input'],$params['mid'],$params['maildir']); 
            } 
            $structure = $obj->decode($params); 
  
        // Called statically but no input 
        } 
        elseif (!isset($this)) 
        { 
            return $this->_error="Called statically and no input given"; 
  
        // Called via an object 
        } 
        else 
        { 
            $this->_include_bodies = isset($params['include_bodies']) 
                                        ? $params['include_bodies'] 
                                        : false; 
            $this->_decode_bodies  = isset($params['decode_bodies']) 
                                        ? $params['decode_bodies'] 
                                        : false; 
            $this->_decode_headers = isset($params['decode_headers']) 
                                        ? $params['decode_headers'] 
                                        : false; 
            if (is_null($this->_header) || is_null($this->_body) 
                || is_null($this->mid) || is_null($this->maildir)) 
            { 
                    $structure = false; 
            } 
            else 
            { 
                $structure = $this->_decode($this->_header, $this->_body, $this->mid, $this->maildir); 
            } 
            if($structure === false) 
            { 
                $structure = $this->_error; 
            } 
        } 
        return $structure; 
    } 
  
    /** 
     * Performs the decoding. Decodes the body string passed to it 
     * If it finds certain content-types it will call itself in a 
     * recursive fashion 
     * 
     * @param string Header section 
     * @param string Body section 
     * @param string mid mime filename 
     * @return object Results of decoding process 
     * @access private 
     */ 

解决方案 »

  1.   

       function _decode($headers, $body, $mid, $maildir, $default_ctype = 'text/plain') 
        { 
            $return = new stdClass; 
            if(!is_null($headers)) 
            { 
                $headers = $this->parseHeaders($headers); 
            } 
            else{ 
                $this->_error="the mime headers is null."; 
                return $this->_error; 
            } 
      
            foreach ($headers as $value) 
            { 
                if (isset($return->headers[$value['name']]) AND !is_array($return->headers[$value['name']])) 
                { 
                    $return->headers[$value['name']]   = array($return->headers[$value['name']]); 
                    $return->headers[$value['name']][] = $value['value']; 
                } 
                elseif (isset($return->headers[$value['name']])) 
                { 
                    $return->headers[$value['name']][] = $value['value']; 
                } 
                else 
                { 
                    $return->headers[$value['name']] = $value['value']; 
                } 
            } 
            reset($headers);  
            //rewinds array's internal pointer to the first element and returns the value of the first array element.  
            while (list($key, $value) = each($headers)) 
            { 
                $headers[$key]['name'] = strtolower($headers[$key]['name']);  
                switch ($headers[$key]['name']) 
                { 
                    case 'content-type': 
                        $content_type = $this->parseHeaderValue($headers[$key]['value']);  
                        if (preg_match('/([0-9a-z+.-]+)/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) 
                        { 
                            $return->ctype_primary   = $regs[1]; 
                            $return->ctype_secondary = $regs[2]; 
                        } 
                        if (isset($content_type['other'])) 
                        { 
                            while (list($p_name, $p_value) = each($content_type['other'])) 
                            { 
                                $return->ctype_parameters[$p_name] = $p_value; 
                            } 
                        } 
                        break; 
      
                    case 'content-disposition': 
                        $content_disposition = $this->parseHeaderValue($headers[$key]['value']); 
                        $return->disposition   = $content_disposition['value']; 
                        if (isset($content_disposition['other'])) 
                        { 
                            while (list($p_name, $p_value) = each($content_disposition['other']))  
                            { 
                                $return->d_parameters[$p_name] = $p_value; 
                            } 
                        } 
                        break; 
                    case 'content-transfer-encoding': 
                        if(!is_null($this->parseHeaderValue($headers[$key]['value']))) 
                        { 
                            $content_transfer_encoding = $this->parseHeaderValue($headers[$key]['value']); 
                        } 
                        else{ 
                            $content_transfer_encoding = ""; 
                        } 
                        break; 
                } 
            } 
      

  2.   

            if (isset($content_type)) 
            { 
                $content_type['value'] = strtolower($content_type['value']); 
                switch ($content_type['value']) 
                { 
                    case 'text': 
                    case 'text/plain': 
                        if($this->_include_bodies) 
                        { 
                            if($this->_decode_bodies) 
                            { 
                                $return->body = isset($content_transfer_encoding['value']) 
                                            ?$this->decodeBody($body,$content_transfer_encoding['value']) 
                                            : $body; 
                            } 
                            else{ 
                                $return->body = $body; 
                            } 
                             
                            if(!isset($content_type['other']['charset'])) 
                            { 
                                $content_type['other']['charset']="gb2312"; 
                            } 
                            if($content_type['other']['charset'] != "") 
                            { 
                                $orim_str = "----- Original Message -----"; 
                                $orim_startpos = strpos($return->body,$orim_str); 
                                if(is_int($orim_startpos)) 
                                { 
                                    $return->body = $return->body; 
                                } 
                                else{ 
                                    $return->body    = str_replace("<","&lt;",$return->body); 
                                    $return->body    = str_replace(">","&gt;",$return->body); 
                                    $return->body    = str_replace("\n"," <br> ",$return->body); 
                                    $return->body    = str_replace(" "," &nbsp; ",$return->body); 
                                } 
                            } 
                        } 
                        $return->body = $this->ConverUrltoLink($return->body); 
                         $return->body    = str_replace(" <br> ","<br>",$return->body); 
                         $return->body    = str_replace(" &nbsp; ","&nbsp;",$return->body); 
                        if(strtolower($return->ctype_parameters['charset'])=="utf-8") 
                        { 
                            $return->body=iconv("utf-8", "gb2312", $return->body); 
                        }                  
                        break; 
         
                    case 'text/html': 
                        if($this->_include_bodies) 
                        { 
                            if($this->_decode_bodies) 
                            { 
                                $return->body = isset($content_transfer_encoding['value']) 
                                            ? $this->decodeBody($body,$content_transfer_encoding['value']) 
                                            : $body; 
                            } 
                            else{ 
                                $return->body = $body; 
                            } 
                        } 
                        $return->body = $this->ConverUrltoLink($return->body);                 
                        if(strtolower($return->ctype_parameters['charset'])=="utf-8") 
                        { 
                            $return->body=iconv("utf-8", "gb2312", $return->body); 
                        } 
                        break; 
                    case 'multipart/mixed': 
                    case 'multipart/alternative': 
                    case 'multipart/digest': 
                    case 'multipart/parallel': 
                    case 'multipart/report': // RFC1892 
                    case 'multipart/signed': // PGP 
                    case 'multipart/related': 
                    case 'application/x-pkcs7-mime': 
                        if(!isset($content_type['other']['boundary'])) 
                        { 
                            $this->_error = 'No boundary found for '.$content_type['value'].' part'; 
                            return false; 
                        } 
                        $default_ctype = (strtolower($content_type['value']) === 'multipart/digest') 
                                            ? 'message/rfc822' 
                                            : 'text/plain'; 
                        $parts = $this->boundarySplit($body, $content_type['other']['boundary']); 
                         
                        if(!isset($return->attlist)) 
                        { 
                            $return->attlist=""; 
                        } 
                        for ($i = 0; $i < count($parts); $i++) 
                        { 
                            list($part_header, $part_body) = $this->splitBodyHeader($parts[$i]); 
                            if (is_null($part_header) || is_null($part_body)) 
                            { 
                                $part = false; 
                            } 
                            else 
                            { 
                                $part = $this->_decode($part_header, $part_body, $mid, $maildir, $default_ctype); 
                            } 
                               if($part === false) 
                            { 
                                   $part =$this->_error;    
                            } 
                            if(!is_null($part->ctype_primary) AND !is_null($part->ctype_secondary)) 
                            { 
                                $part_content_type=$part->ctype_primary."/".$part->ctype_secondary; 
                            } 
                            else{ 
                                $part_content_type=""; 
                            } 
      
                            if(isset($part->body)) 
                            { 
                                if(isset($part->headers['content-transfer-encoding']) AND !is_null($part->headers['content-transfer-encoding'])) 
                                { 
                                    $part->body    = $this->decodeBody($part->body,$part->headers['content-transfer-encoding']); 
                                } 
                                else{ 
                                    $part->body    = $part->body; 
                                } 
                            } 
                            /** 
                             * if part exists with filename/name,save to disk. 
                             */ 
                            if(!isset($part->body)) 
                            { 
                                $part->body = $this->decodeBody($part_body, "base64"); 
                            }  
      

  3.   

    if((($part->ctype_primary."/".$part->ctype_secondary=="message/rfc822") OR ($part->ctype_parameters['name']!="") OR ($part->headers['content-id']!="") OR (isset($part->d_parameters['filename']) AND isset($part->disposition))) AND isset($part->body)) 
                            {                     
                                $att_savename= $mid.".att".$i;    //attachment save name. 
                                $user_cache=$this->maildir; 
                                if(!empty($user_cache) AND !empty($att_savename)) 
                                { 
                                    $att_file=$user_cache."/".$att_savename; 
                                } 
                                else 
                                { 
                                    $att_file=""; 
                                    $return->parts[] = $part; 
                                    break; 
                                } 
                                $att_filename    = $part->ctype_parameters['name']; 
                                if($att_filename=="") 
                                { 
                                    $att_filename = $part->d_parameters['filename']=="" 
                                                    ? $att_filename = "autofile".$i 
                                                    : $part->d_parameters['filename']; 
                                    //if the attachment is the type of rfc/822,and filename is null 
                                    //rename to autofile with ".eml" 
                                    if(($part->ctype_primary."/".$part->ctype_secondary=="message/rfc822") and $att_filename=="autofile".$i) 
                                    { 
                                        $att_filename = $att_filename.".eml";   
                                    } 
                                } 
                                $this->createAttfiles($att_file,$part->body); 
                            $attfile_size=filesize($att_file); 
                                $return->attlist.=$att_filename."|".$attfile_size."|".$att_savename."|".$part_content_type."\n"; 
                                $logName=$user_cache."/.attlog"; 
                                $LogContent = $att_savename."\n"; 
                                $this->CreateLog($logName,$LogContent); 
                                $part->body = ""; //released the used memory 
                            } 
                            else 
                            { 
                                if(isset($part->body)) 
                                { 
                                    $return->body=$part->body; 
                                } 
                            } 
                            $return->parts[] = $part; 
                        } 
                        break; 
                      case 'image/gif': 
                      case 'image/jpeg': 
                        break; 
                    default: 
                        if($this->_include_bodies) 
                        { 
                            if($this->_decode_bodies) 
                            { 
                                $return->body = isset($content_transfer_encoding['value']) 
                                            ?$this->decodeBody($body,$content_transfer_encoding['value']) 
                                            :$body; 
                            } 
                            else{ 
                                $return->body = $body; 
                            } 
                        } 
                        break; 
                } // end switch 
      
            } 
            else { 
                //process if content-type isn't exist. 
                $ctype = explode('/', $default_ctype); 
                $return->ctype_primary   = $ctype[0]; 
                $return->ctype_secondary = $ctype[1]; 
                $this->_include_bodies 
                    ? $return->body = ($this->_decode_bodies 
                                        ? $this->decodeBody($body) 
                                        : $body) 
                    : null; 
                    if($this->_include_bodies) 
                    { 
                        $orim_str = "----- Original Message -----"; 
                        $orim_startpos = strpos($return->body,$orim_str); 
                        if(is_int($orim_startpos)) 
                        { 
                            $return->body = $return->body; 
                        } 
                        else{ 
                            $return->body    = str_replace("\n"," <br> ",$return->body); 
                            $return->body    = str_replace(" "," &nbsp; ",$return->body); 
                        } 
                    } 
                    $return->body    = $this->ConverUrltoLink($return->body); 
                     $return->body    = str_replace(" <br> ","<br>",$return->body); 
                     $return->body    = str_replace(" &nbsp; ","&nbsp;",$return->body); 
                    if(strtolower($return->ctype_parameters['charset'])=="utf-8") 
                    { 
                          $return->body=iconv("utf-8", "gb2312", $return->body); 
                    }                  
            } //end else 
           if(0<strlen($return->attlist)) 
           {         
                   $return->attlist  = substr($return->attlist,0,(strlen($return->attlist)-1));  
           }           return $return; 
        } 
      
        /** 
         * Given a string containing a header and body 
         * section, this function will split them (at the first blank line) and return them. 
         * 
         * @param string Input to split apart 
         * @return array Contains header and body section 
         * @access private 
         */ 
      
        function splitBodyHeader($input) 
        { 
            $pos = strpos($input, $this->_crlf.$this->_crlf); 
            if ($pos === false) 
            { 
                $this->_error = 'Could not split header and body'; 
                return false; 
            } 
      
            $header = substr($input, 0, $pos); 
            $body   = substr($input, $pos+(2*strlen($this->_crlf))); 
            return array($header, $body); 
        } 
      

  4.   

        /** 
         * Parse headers given in $input and return as assoc array. 
         * 
         * @param string Headers to parse 
         * @return array Contains parsed headers 
         * @access private 
         */ 
      
        function parseHeaders($input) 
        { 
            if ($input !== '') 
            { 
                // Unfold the input 
                $input   = preg_replace('/' . $this->_crlf . "(\t| )/", ' ', $input); 
                $headers = explode($this->_crlf, trim($input)); 
      
                foreach ($headers as $value) 
                { 
                    $hdr_name = strtolower(substr($value, 0, $pos = strpos($value, ':'))); 
                    $hdr_value = substr($value, $pos+1); 
                    $return[] = array( 
                                      'name'  => $hdr_name, 
                                      'value' => $this->_decode_headers 
                                                    ? $this->decodeHeader($hdr_value) 
                                                    : $hdr_value 
                                     ); 
                } 
            } 
            else 
            { 
                $return = array(); 
            } 
            return $return; 
        } 
      
        /** 
         * Function to parse a header value, 
         * extract first part, and any secondary 
         * parts (after <img src="http://www.pushad.com/Info/images/smilies/wink.gif" border="0" alt=""> This function is not as 
         * robust as it could be. Eg. header comments 
         * in the wrong place will probably break it. 
         * 
         * @param string Header value to parse 
         * @return array Contains parsed result 
         * @access private 
         */ 
      
        function parseHeaderValue($input) 
        { 
            if (($pos = strpos($input, ';')) !== false) 
            { 
                $return['value'] = trim(substr($input, 0, $pos)); 
                $input = trim(substr($input, $pos+1)); 
                $T_input = explode(";",$input); 
                for($i=0;$i<count($T_input);$i++) 
                { 
                    if (strlen($T_input[$i]) > 0) 
                    { 
                        if(eregi("*([0-9]+)*",$T_input[$i],$regs)) 
                        { 
                            $found=$regs["1"]; 
                            $T_input[$i] = str_replace("*".$found."*","",$T_input[$i]);  
                        } 
                        preg_match_all('/(([[:alnum:]]+)={1}"?([^"]*)"?s?;?)+/i', $T_input[$i], $T_matches); 
                        for ($j = 0; $j < count($T_matches[2]); $j++) 
                        { 
                            $return['other'][strtolower($T_matches[2][$j])] = $T_matches[3][$j]; 
                        } 
                    } 
                } 
            } 
            else 
            { 
                $return['value'] = trim($input); 
            } 
            return $return; 
        } 
      
        /** 
         * This function splits the input based on the given boundary 
         * 
         * @param string Input to parse 
         * @return array Contains array of resulting mime parts 
         * @access private 
         */ 
      
        function boundarySplit($input, $boundary) 
        { 
            $parts = array("",""); 
            $tmp = explode('--'.$boundary, $input); 
            for ($i=1; $i<count($tmp)-1; $i++) 
            { 
                $parts[] = $tmp[$i]; 
            } 
            return $parts; 
        } 
      
     
      

  5.   


      
                                
       /** 
         * Given a header, this function will decode it  according to RFC2047.  
         * Probably not *exactly*  conformant,  
         * but it does pass all the given examples (in RFC2047). 
         * 
         * @param string Input header value to decode 
         * @return string Decoded header value 
         * @access private 
         */ 
          
        function decodeHeader($input) 
        {         
            if(eregi("?(q|b)?",$input,$regs)) 
            { 
                $found=$regs["1"]; 
                if($found=="q") 
                { 
                    $input = str_replace("?".$found."?","?Q?",$input);  
                } 
                if($found=="b") 
                { 
                    $input = str_replace("?".$found."?","?B?",$input);  
                } 
            } 
            // Remove white space between encoded-words 
            $input = preg_replace('/(=?[^?]+?(Q|B)?[^?]*?=)( |' . "\t|" . $this->_crlf . ')+=?/', '1=?', $input); 
            // For each encoded-word... 
            if (preg_match_all('/(=?([^?]+)?(Q|B)?([^?]*)?=)/', $input, $matches)) 
            { 
                for ($i=0; $i< count($matches[0]); $i++) 
                { 
                    $matchew  = $matches[0][$i]; 
                    $encoded  = $matches[1][$i]; 
                    $charset  = strtolower($matches[2][$i]); 
                    $encoding = $matches[3][$i]; 
                    $text     = $matches[4][$i]; 
                    switch ($encoding) 
                    { 
                        case 'B': 
                            $text = base64_decode($text); 
                            break; 
      
                        case 'Q': 
                            $text = quoted_printable_decode($text); 
                            break; 
                    } 
                    switch($charset) 
                    { 
                        case "big5": 
                            $text=iconv("big5", "gb2312",$text); 
                            break; 
                        case "utf-8": 
                            $text=iconv("utf-8", "gb2312",$text); 
                            break; 
                        case "iso-8859-1": 
                            $text=iconv("iso-8859-1", "utf-8",$text); 
                            $text=iconv("utf-8", "gb2312",$text); 
                            break; 
                        default: 
                            break; 
                    }                 
                    $input = str_replace($encoded, $text, $input); 
                } 
            } 
            return $input; 
        } 
      
        /** 
         * Given a body string and an encoding type, 
         * this function will decode and return it. 
         * 
         * @param  string Input body to decode 
         * @param  string Encoding type to use. 
         * @return string Decoded body 
         * @access private 
         */ 
      
        function decodeBody($input, $encoding = '7bit') 
        { 
            $encoding    = strtolower($encoding); 
            switch ($encoding) 
            { 
                case '7bit': 
                    return $input; 
                    break; 
      
                case 'quoted-printable': 
                    return quoted_printable_decode($input); 
                    break; 
      
                case 'base64': 
                    return base64_decode($input); 
                    break; 
      
                default: 
                    return $input; 
            } 
        } 
      
        /** 
         * parse the url to link 
         * 
         * @$input string message text 
         * @return string $linktext parsed text 
         * 
         */ 
      
        function ConverUrltoLink($messagetext) 
        { 
            static $urlSearchArray, $urlReplaceArray; 
            if (empty($urlSearchArray)) 
            { 
                $urlSearchArray = array( 
                "#(^|(?<=[^_a-z0-9-=]\"'/@]|(?<=)]))((https?|ftp|gopher|news|telnet)://|www.)(([(?!/)|[^s[^$!`\"'|{}<>])+)(?![/url|[/img)(?=[,.]*()s|)$|[s[]|$))#siU" 
                ); 
      
                $urlReplaceArray = array( 
                    "<a href='\2\4' target='blank'>\2\4</a>" 
                ); 
            } 
            $linktext = preg_replace($urlSearchArray, $urlReplaceArray , $messagetext); 
            return $linktext; 
        } 
      
        /** 
         * store the parsed attachment files 
         *  
         * @$input string filename 
         * @return boolean variable true return 1,contrariwise,return 0 
         */ 
      
        function createAttfiles($filename,$input) 
        { 
            $content  = $input; 
            $filename = $filename; 
            $handle   = fopen ($filename,"w"); 
            if (!is_writable ($filename)) 
            { 
                $this->_error = 'file:'.$filename.'is readonly,please check file mode.'; 
                return false; 
            } 
            if (!fwrite ($handle,$content)) 
            {  
                $this->_error = 'create file'.$filename.'error!'; 
                return false; 
            }  
            fclose ($handle); 
            return true; 
        } 
         
        /** 
         * append attfile log into the log files 
         *  
         * @$input string filename 
         * @return boolean variable true return 1,contrariwise,return 0 
         */ 
      
        function CreateLog($LogName,$LogContent) 
        { 
            $LogName    = $LogName; 
            $LogContent = $LogContent; 
            if (is_writable($LogName)) 
            { 
                if (!$handle = fopen($LogName, 'a')) { 
                    $this->_error = "can not open file".$LogName; 
                    exit; 
                } 
      
                if (!fwrite($handle, $LogContent)) { 
                    $this->_error = "can not write to file".$LogName; 
                    exit; 
                } 
                fclose($handle); 
            } else { 
                     $this->_error = "can not write to file".$LogName; 
            } 
        }  
      
    }// End of class 
    ?> 
    回4楼,我的目标是解邮件正文的编码,使它能向邮箱那样显示正常的文字,而不是显示编码后的文字
      

  6.   

    思路很简单
    先检查邮件头.找出这两项Content-Type: text/plain; charset=GB2312
    Content-Transfer-Encoding: base64由此来确定其语言编码和转换编码.用PHP调用相应的mb_convert_encoding和base64_decode来处理即可你调一个邮件头看看.就很清楚了但标题和发送者方面要注意.如果带了?GB2312?B,以?=结尾的.这也是编码部份.将标识符头尾先去掉.再用Base64_decode,再用转码.就出来了.
    我这几天正处理这方面事情
      

  7.   

    <?php   
        
      class   smtp   
      {   
      /*   Public   Variables   */   
      var   $smtp_port;   
      var   $time_out;   
      var   $host_name;   
      var   $log_file;   
      var   $relay_host;   
      var   $debug;   
      var   $auth;   
      var   $user;   
      var   $pass;   
        
      /*   Private   Variables   */   
      var   $sock;   
        
      /*   Constractor   */   
      function   smtp($relay_host   =   "",   $smtp_port   =   25,$auth   =   false,$user,$pass)   
      {   
      $this->debug   =   FALSE;   
      $this->smtp_port   =   $smtp_port;   
      $this->relay_host   =   $relay_host;   
      $this->time_out   =   30;   //is   used   in   fsockopen()   
      #   
      $this->auth   =   $auth;//auth   
      $this->user   =   $user;   
      $this->pass   =   $pass;   
      #   
      $this->host_name   =   "localhost";   //is   used   in   HELO   command   
      $this->log_file   =   "";   
        
      $this->sock   =   TRUE;   
      }   
        
      /*   Main   Function   */   
      function   sendmail($to,   $from,   $subject   =   "",   $body   =   "",   $mailtype,   $cc   =   "",   $bcc   =   "",   $additional_headers   =   "")   
      {   
      $mail_from   =   $this->get_address($this->strip_comment($from));   
      $body   =   ereg_replace("(^|(\n))(\\.)",   "\\1.\\3",   $body);   
      $header   .=   "MIME-Version:1.0\r\n";   
      if($mailtype=="HTML"){   
      $header   .=   "Content-Type:text/html; charset=gb2312\r\n";   
      }   
      $header   .=   "To:   ".$to."\r\n";   
      if   ($cc   !=   "")   {   
      $header   .=   "Cc:   ".$cc."\r\n";   
      }   
      $header   .=   "From:   $from<".$from.">\r\n";   
      $header   .=   "Subject: ".$subject."\r\n";   
      $header   .=   $additional_headers;   
      $header   .=   "Date:   ".date("r")."\r\n";   
      $header   .=   "X-Mailer:By   Redhat   (PHP/".phpversion().")\r\n";   
      list($msec,   $sec)   =   explode("   ",   microtime());   
      $header   .=   "Message-ID:   <".date("YmdHis",   $sec).".".($msec*1000000).".".$mail_from.">\r\n";   
      $TO   =   explode(",",   $this->strip_comment($to));   
        
      if   ($cc   !=   "")   {   
      $TO   =   array_merge($TO,   explode(",",   $this->strip_comment($cc)));   
      }   
        
      if   ($bcc   !=   "")   {   
      $TO   =   array_merge($TO,   explode(",",   $this->strip_comment($bcc)));   
      }   
        
      $sent   =   TRUE;   
      foreach   ($TO   as   $rcpt_to)   {   
      $rcpt_to   =   $this->get_address($rcpt_to);   
      if   (!$this->smtp_sockopen($rcpt_to))   {   
      $this->log_write("Error:   Cannot   send   email   to   ".$rcpt_to."\r\n");   
      $sent   =   FALSE;   
      continue;   
      }   
      if   ($this->smtp_send($this->host_name,   $mail_from,   $rcpt_to,   $header,   $body))   {   
      $this->log_write("E-mail   has   been   sent   to   <".$rcpt_to.">\r\n");   
      }   else   {   
      $this->log_write("Error:   Cannot   send   email   to   <".$rcpt_to.">\r\n");   
      $sent   =   FALSE;   
      }   
      fclose($this->sock);   
      $this->log_write("Disconnected   from   remote   host\n");   
      }   
      return   $sent;   
      }   
        
      /*   Private   Functions   */   
        
      function   smtp_send($helo,   $from,   $to,   $header,   $body   =   "")   
      {   
      if   (!$this->smtp_putcmd("HELO",   $helo))   {   
      return   $this->smtp_error("sending   HELO   command");   
      }   
      #auth   
      if($this->auth){   
      if   (!$this->smtp_putcmd("AUTH   LOGIN",   base64_encode($this->user)))   {   
      return   $this->smtp_error("sending   HELO   command");   
      }   
        
      if   (!$this->smtp_putcmd("",   base64_encode($this->pass)))   {   
      return   $this->smtp_error("sending   HELO   command");   
      }   
      }   
      #   
      if   (!$this->smtp_putcmd("MAIL",   "FROM:<".$from.">"))   {   
      return   $this->smtp_error("sending   MAIL   FROM   command");   
      }   
        
      if   (!$this->smtp_putcmd("RCPT",   "TO:<".$to.">"))   {   
      return   $this->smtp_error("sending   RCPT   TO   command");   
      }   
        
      if   (!$this->smtp_putcmd("DATA"))   {   
      return   $this->smtp_error("sending   DATA   command");   
      }   
        
      if   (!$this->smtp_message($header,   $body))   {   
      return   $this->smtp_error("sending   message");   
      }   
        
      if   (!$this->smtp_eom())   {   
      return   $this->smtp_error("sending   <CR><LF>.<CR><LF>   [EOM]");   
      }   
        
      if   (!$this->smtp_putcmd("QUIT"))   {   
      return   $this->smtp_error("sending   QUIT   command");   
      }   
        
      return   TRUE;   
      }   
        
      function   smtp_sockopen($address)   
      {   
      if   ($this->relay_host   ==   "")   {   
      return   $this->smtp_sockopen_mx($address);   
      }   else   {   
      return   $this->smtp_sockopen_relay();   
      }   
      }   
        
      function   smtp_sockopen_relay()   
      {   
      $this->log_write("Trying   to   ".$this->relay_host.":".$this->smtp_port."\n");   
      $this->sock   =   @fsockopen($this->relay_host,   $this->smtp_port,   $errno,   $errstr,   $this->time_out);   
      if   (!($this->sock   &&   $this->smtp_ok()))   {   
      $this->log_write("Error:   Cannot   connenct   to   relay   host   ".$this->relay_host."\n");   
      $this->log_write("Error:   ".$errstr."   (".$errno.")\n");   
      return   FALSE;   
      }   
      $this->log_write("Connected   to   relay   host   ".$this->relay_host."\n");   
      return   TRUE;;   
      }   
        
      function   smtp_sockopen_mx($address)   
      {   
      $domain   =   ereg_replace("^.+@([^@]+)$",   "\\1",   $address);   
      if   (!@getmxrr($domain,   $MXHOSTS))   {   
      $this->log_write("Error:   Cannot   resolve   MX   \"".$domain."\"\n");   
      return   FALSE;   
      }   
      foreach   ($MXHOSTS   as   $host)   {   
      $this->log_write("Trying   to   ".$host.":".$this->smtp_port."\n");   
      $this->sock   =   @fsockopen($host,   $this->smtp_port,   $errno,   $errstr,   $this->time_out);   
      if   (!($this->sock   &&   $this->smtp_ok()))   {   
      $this->log_write("Warning:   Cannot   connect   to   mx   host   ".$host."\n");   
      $this->log_write("Error:   ".$errstr."   (".$errno.")\n");   
      continue;   
      }   
      $this->log_write("Connected   to   mx   host   ".$host."\n");   
      return   TRUE;   
      }   
      $this->log_write("Error:   Cannot   connect   to   any   mx   hosts   (".implode(",   ",   $MXHOSTS).")\n");   
      return   FALSE;   
      }   
      
      

  8.   

      
      function   smtp_message($header,   $body)   
      {   
      fputs($this->sock,   $header."\n".$body);   
      $this->smtp_debug(">   ".str_replace("\n",   "\n".">   ",   $header."\n>   ".$body."\n>   "));   
        
      return   TRUE;   
      }   
        
      function   smtp_eom()   
      {   
      fputs($this->sock,   "\r\n.\r\n");   
      $this->smtp_debug(".   [EOM]\n");   
        
      return   $this->smtp_ok();   
      }   
        
      function   smtp_ok()   
      {   
      $response   =   str_replace("\n",   "",   fgets($this->sock,   512));   
      $this->smtp_debug($response."\n");   
        
      if   (!ereg("^[23]",   $response))   {   
      fputs($this->sock,   "QUIT\n");   
      fgets($this->sock,   512);   
      $this->log_write("Error:   Remote   host   returned   \"".$response."\"\n");   
      return   FALSE;   
      }   
      return   TRUE;   
      }   
        
      function   smtp_putcmd($cmd,   $arg   =   "")   
      {   
      if   ($arg   !=   "")   {   
      if($cmd=="")   $cmd   =   $arg;   
      else   $cmd   =   $cmd." ".$arg;   
      }   
        
      fputs($this->sock,   $cmd."\r\n");   
      $this->smtp_debug(">   ".$cmd."\n");   
        
      return   $this->smtp_ok();   
      }   
        
      function   smtp_error($string)   
      {   
      $this->log_write("Error:   Error   occurred   while   ".$string.".\n");   
      return   FALSE;   
      }   
        
      function   log_write($message)   
      {   
      $this->smtp_debug($message);   
        
      if   ($this->log_file   ==   "")   {   
      return   TRUE;   
      }   
        
      $message   =   date("M   d   H:i:s   ").get_current_user()."[".getmypid()."]:   ".$message;   
      if   (!@file_exists($this->log_file)   ||   !($fp   =   @fopen($this->log_file,   "a")))   {   
      $this->smtp_debug("Warning:   Cannot   open   log   file   \"".$this->log_file."\"\n");   
      return   FALSE;;   
      }   
      flock($fp,   LOCK_EX);   
      fputs($fp,   $message);   
      fclose($fp);   
        
      return   TRUE;   
      }   
        
      function   strip_comment($address)   
      {   
      $comment   =   "\\([^()]*\\)";   
      while   (ereg($comment,   $address))   {   
      $address   =   ereg_replace($comment,   "",   $address);   
      }   
        
      return   $address;   
      }   
        
      function   get_address($address)   
      {   
      $address   =   ereg_replace("([   \t\n])+",   "",   $address);   
      $address   =   ereg_replace("^.*<(.+)>.*$",   "\\1",   $address);   
        
      return   $address;   
      }   
        
      function   smtp_debug($message)   
      {   
      if   ($this->debug)   {   
      echo   $message;   
      }   
      }   
      }   
      ?>   
    这个可以自行设置smtp服务器,如果你服务器上没有smtp的话用这个绝对好, 还能发附件 很强大。
      

  9.   

    既然你已经把pear mimeDecode类发出来了,我建议你还是用这个类吧,这个挺好用的.<?php   
    function _log($msg)      
    {      
        if($msg != "")      
        {      
            echo $msg . "";      
            exit();      
        }      
    }          
    function retrieve_pop3_msgs($host, $port, $user, $pass ,$apop, $max_msgs)      
    {      
        include_once ('Net/POP3.php');      
        //打开一个op3连接      
        $pop3 =& new Net_POP3();      
        //设置调试模式      
        //$pop3->setDebug();      
        //连接服务器      
        if (!$pop3->connect($host, $port))      
        {      
            $m2f_error_msg = "连接POP3服务器发生错误 $host:$port";      
            _log($m2f_error_msg);      
        }         
        //登录      
        $result = $pop3->login($user, $pass , ($apop == '1' ? 'APOP' : 'USER'));      
        if (PEAR::isError($result))      
        {      
            $m2f_error_msg = '登录pop3服务器时发生错误: ' . $result->getMessage();      
            _log($m2f_error_msg);      
        }      
        //获取邮件总数      
        $total = $pop3->numMsg();      
        if ($total === false)      
        {      
            $m2f_error_msg = '接收pop邮件时发生错误';      
            _log($m2f_error_msg);      
        }      
        $total = ($max_msgs == 0) ? $total : (($max_msgs < $total) ? $max_msgs : $total);       
              
        //邮件数组      
        $mail_msgs = array();      
              
        //获取邮件      
        for ($x = 1; $x <= $total; $x++)      
        {      
            $thisMessage = $pop3->getMsg($x);      
            if ($thisMessage === false)      
            {      
                $m2f_error_msg = '接收邮件时发生错误: ' . $x;      
                _log($m2f_error_msg);      
            }      
            $mail_msgs[$x] = $thisMessage;      
        }         
        return $mail_msgs;      
    }      
    //调用, 以sohu为例       
    include_once ('Mail/mimeDecode.php');    
    $mail_msgs = retrieve_pop3_msgs('pop3.sohu.com', '110', '邮箱名', '密码', 1, 1);   
    foreach ($mail_msgs as $message_key => $raw_mail_msg)   
    {   
       $raw_mail_msg = trim($raw_mail_msg);   
       $params = array();    
       $params['include_bodies'] = TRUE;    
       $params['decode_bodies']  = TRUE;    
       $params['decode_headers'] = TRUE;    
       $params['input'] = $raw_mail_msg;      
       $structure = Mail_mimeDecode::decode($params);   
       //可以查看类实例结构   
       print_r($structure);   
    }  
    更详细的请参看我的blog.
    http://blog.sevenight.com/index.php?m=blog&a=show&id=75
      

  10.   

    几个月前,费劲功夫来研究phpbb2 m2f功能,呵呵,所以对这部分多少还了解点.
    有功夫可以讨论一下,共同学习吗!
      

  11.   

    楼上的,我这个据说是别人改的PEAR的类,但是我自己琢磨了半天都没高通调用的方法,很多东西都看的似懂非懂...
    郁闷死我了,解邮件的标题可以说非常容易的就搞通了,就解BODY,搞了一个通宵没通....
    你要有时间的话很希望和你探讨一下。
      

  12.   

    PHP有现在的mailprase函数...何必再去写...
    PECL里有......手册也里有......
      

  13.   

    自己的服务器就好说了,可是别人的服务器,从4.2以后PEAR就不是标准的安装项目了.....
      

  14.   

    就是很多email的客户端都做得不是很完美email的头有非标准的实现
      

  15.   

    就是想找点现成的方法,我觉得这个东西应该好多人开发过模块了。
    实在没办法的话只能按照8楼的方法了。没办法的办法啊.....
    能有现成的最好了,因为这东西编码太多了,自己写难免疏漏。
    我还分析了几个WEBMAIL,来回调来调去的函数好多,我又是对PHP不是特别熟悉,看的头都大了。
      

  16.   

    调出Email的头,判断是什么编码和用base64编码的等信息。然后逆运算那样,确定用base64的,用base64_decode进行解码,然后进行什么类似iconv、mb_开头之类的编码转换的函数进行转换编码。再处理的就是内容了,这部分不用讲了。这个帖子的技术含量和含金量很高啊!哈哈
      

  17.   

    还有,这里详细的介绍了,不止有注释,还是人工解释,是PHP接收邮件的全过程以及它的代码各部分处理过程,还有解码的过程,说真的,关于PHP接收邮件的方法真的很少见,我自己反正没做过,呵呵,网页地址:http://www.linux-cn.com/html/network/mail/20070531/44924.html
      

  18.   

    楼上的那个好像没有涉及到BODY的解码。涉及的是邮件接收,邮件接收过来以后的内容一般是经过MIME编码的,如果不能解码,就会显示乱七八糟的东西。我也累了,休息了,搞这些东西真的头大。不过不连续搞又怕第二天起来没思路了,烦人啊。jakey9826 如果能看到的话,我想问一下$params['input'] = $raw_mail_msg; ,这个$raw_mail_msg是什么东西,怎么得到的?因为一般收到的信的HEAD和BODY都是数组,而$params['input']这个应该是一个字符串变量,这个$raw_mail_msg存储的是什么内容么?还有能不能分享一下你的Net/POP3.php和Mail/mimeDecode.php这两个文件?
    MIMEDECODE可能和我发的这个类内容差不多,不过POP3的自定义的差别就大了,这里边可能涉及到很多关联的东西吧。
      

  19.   

    Body部份一样有编码指定.这个你不用担心.如果没指定的纯正文.就沿用邮件头里的.
    你开一个邮件源文一看就全清楚了.
    无非就是 :编码正逆转换+正则提取.
    如果带图片的再加点header头输出.
      

  20.   

    jakey9826 的BLOG 我看了一下,主要还是pear的问题。如何才能用免安装的PEAR或者不用它呢...因为这要别人的服务器上支持才行....
      

  21.   

    可以看看igenus的读邮件那段代码!prev.php<?php
    /*-
     * iGENUS webmail 
     * 
     * Copyright (c) 1999-2001 by iGENUS Inc.
     * All rights reserved.
     * Author: Qiong Wu <[email protected]>
     *
     * $Id: prev.php,v 1.21 2004/07/13 07:33:50 wuqiong Exp $
     */if(CFG_DEBUG) $timebegin = gettimeofday();include "include/login_inc.php";
    include "config/config_inc.php";
    include "include/fun_inc.php";
    include "include/prev_inc.php";/* 入口参数: 
     * Mailbox 邮箱
     * Num 邮件序号
     * Lang 语言
     */
    $get_Mailbox = trim($_GET['Mailbox']);
    $get_Num     = trim($_GET['Num']);
    $get_Lang    = trim($_GET['Lang']);// 检查 $get_Mailbox 参数的可靠性,生成邮箱列表文件名
    if( !(list($listfile,$SMailbox) = GetMailboxFolder($get_Mailbox)) ) die("无效的邮箱参数!");
    $listfile = "$CFG_TEMP/$SG_DOMAIN/$SG_USERNAME/$listfile";//从 list 文件中读取邮件基本信息
    ($FD_LIST = fopen($listfile,"r"))||die("Error open list file!");
    $i=0;
    while(!feof($FD_LIST)){
    $line = fgets($FD_LIST,1024);
    $i++;
    if( $i==$get_Num ) break;
    }
    fclose($FD_LIST);
    if(empty($line)) die("Error read list file!");
    if($i>$get_Num) die("参数错误:无效的邮件序号");list($n,$Key,$IsNew,$File,$FromName,$From,$Subject,$Date,$Size,) = split("\t",$line,10);
    list($null,$Date) = Date2Str($Date,$CFG_GMT);$mailfile = "$SG_HOME/Maildir/$SMailbox/$IsNew/$File";if(!file_exists($mailfile))
    {
        $home = $SG_HOME . "/Maildir/".$SMailbox."/cur";
    $handle=opendir($home); while (($file = readdir($handle))!==false)
    {
         if (substr_count($file, $File)==1)
         {
    $mailfile = "$SG_HOME/Maildir/$SMailbox/cur/$file";
         }
    }
    closedir($handle);
    }
    if(file_exists($mailfile))
    ($FD_MAIL = fopen($mailfile,"r")) || die("Error open mail file $file!");
    else
    exit(); $header = Parse_head_List($FD_MAIL);
    // print_r($FD_MAIL);
    // print_r($header);// $From  = $header["fromemail"];
    // $FromName  = $header["fromname"];
    $To  = $header["to"];
    $Content_Type = strtolower($header["content-type"]);
    $Boundary = $header["boundary"];
    $Content_Transfer_Encoding = strtolower($header["content-transfer-encoding"]);
    $Charset = $header["charset"];
    $Subject = $header["subject"];
    unset($header); // Free memory

    $bodylistfile = "$CFG_TEMP/$SG_DOMAIN/$SG_USERNAME/list_body";
    RemoveBody($bodylistfile); // remove body part prev or next mail // 打开 list_body 文件
    ($FD_BODYLIST = fopen("$bodylistfile","w+")) || die("Error open body list file");

    $out = "$FromName\t$From\t$Subject\t$Date\t$Size\t$Content_Type\t$Content_Transfer_Encoding\n";
    fputs($FD_BODYLIST, $out); // decode body
    // 入口参数:$Content_Type, $FD_MAIL, $FD_BODYLIST

    if( preg_match("/^multipart/",$Content_Type) && empty($Boundary) ) $Content_Type = '';

    switch($Content_Type){
    case "multipart/mixed":
    case "multipart/related":
    case "multipart/alternative":
    case "multipart/report":
    Decode_multipart($FD_MAIL,$FD_BODYLIST,$Boundary,$Content_Type);
    break;

    case "text/html":
    Decode_text($FD_MAIL,$FD_BODYLIST,"unknown.html",$Content_Transfer_Encoding,$Content_Type,$Charset);
    break;

    case "text/plain":
    case "":
    default:
    Decode_text($FD_MAIL,$FD_BODYLIST,"unknown.txt",$Content_Transfer_Encoding,$Content_Type,$Charset);
    }// 判断是否有附件
    // 用 $i 来统计附件数量
    // 
    fseek($FD_BODYLIST,0,SEEK_SET);
    $i = 0;
    $line = fgets($FD_BODYLIST,1024); // skip the first line
    while(($line=fgets($FD_BODYLIST,1024)) && !feof($FD_BODYLIST)){
    list($filename,$type,$size,$disposition,$id,$location) = split("\t",$line,6);
    if($disposition=='attachment' || 
    ($disposition=='inline' && substr_count($filename,'unkown')==1 ) ||
    ($disposition=='inline' && $type=='application/x-msdownload') || 
    ($disposition=='inline' && $type!="text/plain" && $type!="text/html") || 
    $type=='application/octet-stream' ||
    ( empty($location) && empty($id)) ){
    $i++;
    }
    }// 结束邮件解码
    //
    fclose($FD_BODYLIST);
    fclose($FD_MAIL);// 标记邮件已读
    if( $CFG_Prev_IsRead=='yes' ){
        // Move mail file from new to cur
        if($IsNew == "new")
        {
         if(file_exists("$SG_HOME/Maildir/$SMailbox/new/$File")) {
         @link("$SG_HOME/Maildir/$SMailbox/new/$File",
         "$SG_HOME/Maildir/$SMailbox/cur/$File:2,S");
         @unlink("$SG_HOME/Maildir/$SMailbox/new/$File");
         }
        }else
        {
        $home = $SG_HOME . "/Maildir/".$SMailbox."/cur";
    $handle=opendir($home);

    while (($file = readdir($handle))!==false)
    {
         if (substr_count($file, $File)==1)
         {
         // 解析 Maildir 文件标记
    list($basefile, $flag) = split(":", $file);
    $tag = split(",", $flag);
    // 查找该文件是否有已读标记
    $isread = 0;
    foreach($tag as $val)
    if($val=="S") $isread = 1;
    // 如果没有做已读标记
    if($isread==0)
    {
         @link("$SG_HOME/Maildir/$SMailbox/cur/$file",
         "$SG_HOME/Maildir/$SMailbox/cur/$file"."S");
         @unlink("$SG_HOME/Maildir/$SMailbox/cur/$file");
    }
         }
    }
    closedir($handle);
        }
        
    }// load Template
    $OUT['CHARSET'] = $CFG_CHARSET[$Get_Lang];          // 页面字符编码设置
    $OUT['SRC_HEADER'] = "header.php?Mailbox=$get_Mailbox&Num=$get_Num&Lang=$get_Lang";
    $OUT['SRC_BODY'] = "read.php?Mailbox=$get_Mailbox&Num=$get_Num&Type=$Content_Type";
    $OUT['ATTACHNUM'] = $i;
    $OUT['SRC_ATTACH'] = "attachlist.php?Mailbox=$get_Mailbox&Num=$get_Num";$OUT['LANG']    = $Get_Lang;                        // 登录后显示语言include "template/$CFG_TEMPLATE/_prev.php";
    ?>
      

  22.   


    function sendmail($toemails, $subject, $message, $from='') {
    global $_SC, $_SCONFIG, $_SGLOBAL, $space;

    include template('sendmail');
    $message = ob_get_contents();
    obclean();

    include_once(S_ROOT.'./data/data_mail.php');
    $mail = $_SGLOBAL['mail'];

    //邮件头的分隔符
    $maildelimiter = $mail['maildelimiter'] == 1 ? "\r\n" : ($mail['maildelimiter'] == 2 ? "\r" : "\n");
    //收件人地址中包含用户名
    $mailusername = isset($mail['mailusername']) ? $mail['mailusername'] : 1;
    //端口
    $mail['port'] = $mail['port'] ? $mail['port'] : 25;
    $mail['mailsend'] = $mail['mailsend'] ? $mail['mailsend'] : 1;

    //发信者
    $email_from = $from == '' ? '=?'.$_SC['charset'].'?B?'.base64_encode($_SCONFIG['sitename'])."?= <".$_SCONFIG['adminemail'].">" : (preg_match('/^(.+?) \<(.+?)\>$/',$from, $mats) ? '=?'.$_SC['charset'].'?B?'.base64_encode($mats[1])."?= <$mats[2]>" : $from); foreach($toemails as $key => $toemail) {
    $toemails[$key] = preg_match('/^(.+?) \<(.+?)\>$/',$toemail, $mats) ? ($mailusername ? '=?'.$_SC['charset'].'?B?'.base64_encode($mats[1])."?= <$mats[2]>" : $mats[2]) : $toemail;
    }
    $email_to = implode(',', $toemails);

    $email_subject = '=?'.$_SC['charset'].'?B?'.base64_encode(preg_replace("/[\r|\n]/", '', '['.$_SCONFIG['sitename'].'] '.$subject)).'?=';
    $email_message = chunk_split(base64_encode(str_replace("\n", "\r\n", str_replace("\r", "\n", str_replace("\r\n", "\n", str_replace("\n\r", "\r", $message))))));

    $headers = "From: $email_from{$maildelimiter}X-Priority: 3{$maildelimiter}X-Mailer: UCENTER_HOME ".X_VER."{$maildelimiter}MIME-Version: 1.0{$maildelimiter}Content-type: text/html; charset=$_SC[charset]{$maildelimiter}Content-Transfer-Encoding: base64{$maildelimiter}";

    if($mail['mailsend'] == 1) {
    if(function_exists('mail') && @mail($email_to, $email_subject, $email_message, $headers)) {
    return true;
    }
    return false;

    } elseif($mail['mailsend'] == 2) { if(!$fp = fsockopen($mail['server'], $mail['port'], $errno, $errstr, 30)) {
    runlog('SMTP', "($mail[server]:$mail[port]) CONNECT - Unable to connect to the SMTP server", 0);
    return false;
    }
      stream_set_blocking($fp, true);

    $lastmessage = fgets($fp, 512);
    if(substr($lastmessage, 0, 3) != '220') {
    runlog('SMTP', "$mail[server]:$mail[port] CONNECT - $lastmessage", 0);
    return false;
    }

    fputs($fp, ($mail['auth'] ? 'EHLO' : 'HELO')." UCenter Home\r\n");
    $lastmessage = fgets($fp, 512);
    if(substr($lastmessage, 0, 3) != 220 && substr($lastmessage, 0, 3) != 250) {
    runlog('SMTP', "($mail[server]:$mail[port]) HELO/EHLO - $lastmessage", 0);
    return false;
    }

    while(1) {
    if(substr($lastmessage, 3, 1) != '-' || empty($lastmessage)) {
      break;
      }
      $lastmessage = fgets($fp, 512);
    }

    if($mail['auth']) {
    fputs($fp, "AUTH LOGIN\r\n");
    $lastmessage = fgets($fp, 512);
    if(substr($lastmessage, 0, 3) != 334) {
    runlog('SMTP', "($mail[server]:$mail[port]) AUTH LOGIN - $lastmessage", 0);
    return false;
    }

    fputs($fp, base64_encode($mail['auth_username'])."\r\n");
    $lastmessage = fgets($fp, 512);
    if(substr($lastmessage, 0, 3) != 334) {
    runlog('SMTP', "($mail[server]:$mail[port]) USERNAME - $lastmessage", 0);
    return false;
    }

    fputs($fp, base64_encode($mail['auth_password'])."\r\n");
    $lastmessage = fgets($fp, 512);
    if(substr($lastmessage, 0, 3) != 235) {
    runlog('SMTP', "($mail[server]:$mail[port]) PASSWORD - $lastmessage", 0);
    return false;
    }

    $email_from = $mail['from'];
    }

    fputs($fp, "MAIL FROM: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_from).">\r\n");
    $lastmessage = fgets($fp, 512);
    if(substr($lastmessage, 0, 3) != 250) {
    fputs($fp, "MAIL FROM: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_from).">\r\n");
    $lastmessage = fgets($fp, 512);
    if(substr($lastmessage, 0, 3) != 250) {
    runlog('SMTP', "($mail[server]:$mail[port]) MAIL FROM - $lastmessage", 0);
    return false;
    }
    }

    foreach($toemails as $toemail) {
    $toemail = trim($toemail);
    if($toemail) {
    fputs($fp, "RCPT TO: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $toemail).">\r\n");
    $lastmessage = fgets($fp, 512);
    if(substr($lastmessage, 0, 3) != 250) {
    fputs($fp, "RCPT TO: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $toemail).">\r\n");
    $lastmessage = fgets($fp, 512);
    runlog('SMTP', "($mail[server]:$mail[port]) RCPT TO - $lastmessage", 0);
    return false;
    }
    }
    }

    fputs($fp, "DATA\r\n");
    $lastmessage = fgets($fp, 512);
    if(substr($lastmessage, 0, 3) != 354) {
    runlog('SMTP', "($mail[server]:$mail[port]) DATA - $lastmessage", 0);
    return false;
    }

    $headers .= 'Message-ID: <'.sgmdate('YmdHs').'.'.substr(md5($email_message.microtime()), 0, 6).rand(100000, 999999).'@'.$_SERVER['HTTP_HOST'].">{$maildelimiter}";

    fputs($fp, "Date: ".sgmdate('r')."\r\n");
    fputs($fp, "To: ".$email_to."\r\n");
    fputs($fp, "Subject: ".$email_subject."\r\n");
    fputs($fp, $headers."\r\n");
    fputs($fp, "\r\n\r\n");
    fputs($fp, "$email_message\r\n.\r\n");
    $lastmessage = fgets($fp, 512);
    if(substr($lastmessage, 0, 3) != 250) {
    runlog('SMTP', "($mail[server]:$mail[port]) END - $lastmessage", 0);
    }
    fputs($fp, "QUIT\r\n");

    return true; } elseif($mail['mailsend'] == 3) { ini_set('SMTP', $mail['server']);
    ini_set('smtp_port', $mail['port']);
    ini_set('sendmail_from', $email_from);

    if(function_exists('mail') && @mail($email_to, $email_subject, $email_message, $headers)) {
    return true;
    }
    return false;
    }
    }这个可是非常好的邮件发送方法
      

  23.   

    回30楼,受益匪浅,谢谢。我的HEAD和BODY确实是经过处理后的。分解成了SUBJECT,FROM,TO等数组。等我好好研究一下啊。
    今天这个帖子先结贴,因为明天后天大后天放假,我今天回家,只能先结贴了。剩下的分数等我4号回来继续开贴讨论。如能解决问题,必将全部奉送。
    欢迎大家继续讨论。
      

  24.   

    大家先在这个帖子里讨论吧,因为限制一个帖子的分数为100(我不是长泡CSDN,不知道能不能把帖子的分数追加),所以单个帖子大家分的话也没多少分。
    我单开帖子给分,如果对我帮助大的,肯定会多多奉送的。
      

  25.   

    还在讨论这个...汗....来个终结的吧...1.PECL里的mailprase处理类.绝对很好用
    2. PHP-CLASS里有一个.比我昨天写的还好.  想要示例的我放空间一周,自己去下  http://www.10tiao.cn/yu/mail.rar3.核心仍然不外乎:正则,逆反编码...其实看看邮件头.真的就什么都知道了.这东西 就是烦杂.技术上不算复杂.