发一个改写的一个邮件解码类!部份邮件解码率超过OutLook,Foxmail
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
*/
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;
}
}
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 ( "<" , "<" , $return -> body );
$return -> body = str_replace ( ">" , ">" , $return -> body );
$return -> body = str_replace ( "\n" , "
```
```
" , $return -> body );
$return -> body = str_replace ( " " , " " , $return -> body );
}
}
}
$return -> body = $this -> ConverUrltoLink ( $return -> body );
$return -> body = str_replace ( "
```
```
" , "
```
```
" , $return -> body );
$return -> body = str_replace ( " " , " " , $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'</Published At