📄 class_mimedecode.php
字号:
<?php/*** +----------------------------- IMPORTANT ------------------------------+* | Usage of this class compared to native php extensions such as |* | mailparse or imap, is slow and may be feature deficient. If available|* | you are STRONGLY recommended to use the php extensions. |* +----------------------------------------------------------------------+** Mime Decoding class** This class will parse a raw mime email and return* the structure. Returned structure is similar to* that returned by imap_fetchstructure().** USAGE: (assume $input is your raw email)** $decode = new Mail_mimeDecode($input);* $structure = $decode->decode();* print_r($structure);** Or statically:** $params['input'] = $input;* $structure = Mail_mimeDecode::decode($params);* print_r($structure);** TODO:* - Implement further content types, eg. multipart/parallel,* perhaps even message/partial.** @author Richard Heyes* @version $Revision: 1.1 $* @package Mail*/class Mail_mimeDecode{ /** * The raw email to decode * @var string */ var $_input; /** * The header part of the input * @var string */ var $_header; /** * The body part of the input * @var string */ var $_body; /** * If an error occurs, this is used to store the message * @var string */ var $_error; /** * Flag to determine whether to include bodies in the * returned object. * @var boolean */ var $_include_bodies; /** * Flag to determine whether to decode bodies * @var boolean */ var $_decode_bodies; /** * Flag to determine whether to decode headers * @var boolean */ var $_decode_headers; /** * If invoked from a class, $this will be set. This has problematic * connotations for calling decode() statically. Hence this variable * is used to determine if we are indeed being called statically or * via an object. */ var $mailMimeDecode; /** * 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 Mail_mimeDecode($input) { list($header, $body) = $this->_splitBodyHeader($input); $this->_input = $input; $this->_header = $header; $this->_body = $body; $this->_decode_bodies = false; $this->_include_bodies = true; $this->mailMimeDecode = 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->mailMimeDecode) AND isset($params['input'])) { $obj = new Mail_mimeDecode($params['input']); $structure = $obj->decode($params); // Called statically but no input } elseif (!isset($this->mailMimeDecode)) { $this->_error = 'Called statically and no input given'; return false; // 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; $structure = $this->_decode($this->_header, $this->_body); } 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 * @return object Results of decoding process * @access private */ function _decode($headers, $body, $default_ctype = 'text/plain') { $return = new stdClass; $headers = $this->_parseHeaders($headers); foreach ($headers as $value) { if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) { $return->headers[strtolower($value['name'])] = array($return->headers[strtolower($value['name'])]); $return->headers[strtolower($value['name'])][] = $value['value']; } elseif (isset($return->headers[strtolower($value['name'])])) { $return->headers[strtolower($value['name'])][] = $value['value']; } else { $return->headers[strtolower($value['name'])] = $value['value']; } } reset($headers); 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': $content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']); break; } } if (isset($content_type)) { switch (strtolower($content_type['value'])) { case 'text/plain': $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; break; case 'text/html': $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; break; case 'multipart/parallel': case 'multipart/report': // RFC1892 case 'multipart/signed': // PGP case 'multipart/digest': case 'multipart/alternative': case 'multipart/related': case 'multipart/mixed': 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']); for ($i = 0; $i < count($parts); $i++) { list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]); $part = $this->_decode($part_header, $part_body, $default_ctype); $return->parts[] = $part; } break; case 'message/rfc822': $obj = &new Mail_mimeDecode($body); $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies)); unset($obj); break; default: if(!isset($content_transfer_encoding['value'])) $content_transfer_encoding['value'] = '7bit'; $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null; break; } } else { $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; } return $return; } /** * Given the output of the above function, this will return an * array of references to the parts, indexed by mime number. * * @param object $structure The structure to go through * @param string $mime_number Internal use only. * @return array Mime numbers */ function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '') { $return = array(); if (!empty($structure->parts)) { if ($mime_number != '') { $structure->mime_id = $prepend . $mime_number; $return[$prepend . $mime_number] = &$structure; } for ($i = 0; $i < count($structure->parts); $i++) { if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') { $prepend = $prepend . $mime_number . '.'; $_mime_number = ''; } else { $_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1)); } $arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend); foreach ($arr as $key => $val) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -