作者 邓超

m

... ... @@ -54,7 +54,7 @@ class DataArray {
}
}
return null;
return '';
}
/**
... ...
... ... @@ -57,18 +57,70 @@ class Body {
// 是否是多段
$boundary = $this->msg->header->getBoundary();
if($boundary){
// 切割成块
$items = explode($boundary,$this->raw);
// 切割成块 boundary 的结束符号 前后都会多2个--
$items = explode($boundary,
str_replace('--'.$boundary.'--',$boundary,$this->raw)
);
// 第一个块和最后一块 是没用的块
array_shift($items);array_pop($items);
foreach ($items as $item){
$this->items[] = $this->parseItem($item);
}
}
// 不是多块级
if(stripos($this->msg->header->get('content-type'),'text/')===0){
$this->parseRawHtml();
}
}
/**
* 解析 不是多块级的邮件体 直接就是html或者text的
* @author:dc
* @time 2024/9/21 11:37
*/
private function parseRawHtml() {
$data = $this->parseMimeHeader('Content-Type: '.$this->msg->header->get('content-type'));
// 设置编码规则
if($this->msg->header->get('Content-Transfer-Encoding')){
$data->set('Content-Transfer-Encoding',$this->msg->header->get('Content-Transfer-Encoding'));
}
// 是否是item fetch
if(preg_match('/^\* \d+ FETCH \(/',$this->raw)){
$body = mb_substr(trim($this->raw),strpos($this->raw,'(')+1,-1);
// 打散成数组
$body = explode("\r\n",trim($body));
/***************** start 第一行处理 **************/
// 第一行 UID 1568602721 RFC822.TEXT {589}
$first = explode(' ',$body[0]);
while (1){ if(str_starts_with(array_shift($first), 'RFC822.')) break; }
$first = array_values($first);
$first[0] = preg_replace("/^\{\d+\}/",'',$first[0]);
// 第一行的结果就是 踢出 UID 1568602721 RFC822.TEXT {589}
$body[0] = implode("\r\n",$first);
/***************** end 第一行处理 **************/
// -----------------------------------------------------------
/***************** start 最后一行处理 **************/
// 最后一行可能是 UID 1568602721 微软的就是
$end = trim(end($body));
$end = preg_replace("/(UID \d+)|(FLAGS \([\\a-z* ]*\))/",'',$end);
if(!trim($end)){ array_pop($body); }
/***************** end 最后一行处理 **************/
// 再次组装成字符串
$data->body = trim(implode("\r\n",$body));
$this->items[] = $this->bodyDeCode($data);
}
}
/**
* 解析每个 块
* @param string $body 块字符串
... ... @@ -79,25 +131,35 @@ class Body {
protected function parseItem(string $body):DataArray {
list($mime_header,$text) = explode("\r\n\r\n",$body,2);
// 解析头部
$data = $this->parseMimeHeader($mime_header);
$data->body = $text;
return $this->bodyDeCode($data);
}
/**
* @param DataArray $data
* @return DataArray
* @author:dc
* @time 2024/9/21 11:39
*/
private function bodyDeCode(DataArray $data):DataArray {
// 处理body体 的编码
switch ($data->get('Content-Transfer-Encoding')){
case 'quoted-printable':{
$text = quoted_printable_decode($text);break;
$data->body = quoted_printable_decode($data->body);break;
}
case 'base64':{
$text = base64_decode($text);break;
$data->body = base64_decode($data->body);break;
}
}
$data->body = $text;
return $data;
}
/**
* 解析邮件体里面的每个块 头部
* @param string $header
... ... @@ -126,11 +188,13 @@ class Body {
$contentType = explode(' ',trim(str_replace(';',' ',$data->get('Content-Type'))));
foreach ($contentType as $ct){
$ct = trim($ct);
// 这个才是真的类型
if(str_contains($ct,'/')){
$data->set('Content-Type',$ct);
}elseif (str_contains($ct,'=')){
// 这里包含了其他
list($name,$val) = explode('=',$ct);
$data->set($name,trim($val));
$data->set($name,trim(str_replace('"','',$val)));
}
}
}
... ... @@ -168,9 +232,10 @@ class Body {
public function getHtml():string {
foreach ($this->items as $item){
if($item->eq('content-type','text/html')){
return $item->body;
return $item->body ? : '';
}
}
return '';
}
/**
... ...