📄 mimedecode.php
字号:
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/appledouble': // Appledouble mail 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); if($part === false) $part = $this->raiseError($this->_error); $return->parts[] = $part; } break; case 'message/rfc822': $obj = &new Mail_mimeDecode($body); $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies, 'decode_bodies' => $this->_decode_bodies, 'decode_headers' => $this->_decode_headers)); 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) { $no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key]; } } } else { if ($mime_number == '') { $mime_number = '1'; } $structure->mime_id = $prepend . $mime_number; $no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure; } 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) { if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) { return array($match[1], $match[2]); } $this->_error = 'Could not split header and body'; return false; } /** * 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("/\r?\n/", "\r\n", $input); $input = preg_replace("/\r\n(\t| )+/", ' ', $input); $headers = explode("\r\n", trim($input)); foreach ($headers as $value) { $hdr_name = substr($value, 0, $pos = strpos($value, ':')); $hdr_value = substr($value, $pos+1); if($hdr_value[0] == ' ') $hdr_value = substr($hdr_value, 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 ;) 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)); if (strlen($input) > 0) { // This splits on a semi-colon, if there's no preceeding backslash // Now works with quoted values; had to glue the \; breaks in PHP // the regex is already bordering on incomprehensible $splitRegex = '/([^;\'"]*[\'"]([^\'"]*([^\'"]*)*)[\'"][^;\'"]*|([^;]+))(;|$)/'; preg_match_all($splitRegex, $input, $matches); $parameters = array(); for ($i=0; $i<count($matches[0]); $i++) { $param = $matches[0][$i]; while (substr($param, -2) == '\;') { $param .= $matches[0][++$i]; } $parameters[] = $param; } for ($i = 0; $i < count($parameters); $i++) { $param_name = trim(substr($parameters[$i], 0, $pos = strpos($parameters[$i], '=')), "'\";\t\\ "); $param_value = trim(str_replace('\;', ';', substr($parameters[$i], $pos + 1)), "'\";\t\\ "); if ($param_value[0] == '"') { $param_value = substr($param_value, 1, -1); } $return['other'][$param_name] = $param_value; $return['other'][strtolower($param_name)] = $param_value; } } } 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(); $bs_possible = substr($boundary, 2, -2); $bs_check = '\"' . $bs_possible . '\"'; if ($boundary == $bs_check) { $boundary = $bs_possible; } $tmp = explode('--' . $boundary, $input); for ($i = 1; $i < count($tmp) - 1; $i++) { $parts[] = $tmp[$i]; } return $parts; } /** * 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) { // Remove white space between encoded-words $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input); // For each encoded-word... while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) { $encoded = $matches[1]; $charset = $matches[2]; $encoding = $matches[3]; $text = $matches[4]; switch (strtolower($encoding)) { case 'b': $text = base64_decode($text); break; case 'q': $text = str_replace('_', ' ', $text); preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); foreach($matches[1] as $value) $text = str_replace('='.$value, chr(hexdec($value)), $text); break; } $input = str_replace($encoded, $text, $input); } return $input; } /** * Given a body string and an encoding type, * this function will decode and return it. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -