正在显示
2 个修改的文件
包含
76 行增加
和
11 行删除
| @@ -57,18 +57,70 @@ class Body { | @@ -57,18 +57,70 @@ class Body { | ||
| 57 | // 是否是多段 | 57 | // 是否是多段 | 
| 58 | $boundary = $this->msg->header->getBoundary(); | 58 | $boundary = $this->msg->header->getBoundary(); | 
| 59 | if($boundary){ | 59 | if($boundary){ | 
| 60 | - // 切割成块 | ||
| 61 | - $items = explode($boundary,$this->raw); | 60 | + // 切割成块 boundary 的结束符号 前后都会多2个-- | 
| 61 | + $items = explode($boundary, | ||
| 62 | + str_replace('--'.$boundary.'--',$boundary,$this->raw) | ||
| 63 | + ); | ||
| 62 | // 第一个块和最后一块 是没用的块 | 64 | // 第一个块和最后一块 是没用的块 | 
| 63 | array_shift($items);array_pop($items); | 65 | array_shift($items);array_pop($items); | 
| 64 | foreach ($items as $item){ | 66 | foreach ($items as $item){ | 
| 65 | $this->items[] = $this->parseItem($item); | 67 | $this->items[] = $this->parseItem($item); | 
| 66 | } | 68 | } | 
| 67 | } | 69 | } | 
| 70 | + // 不是多块级 | ||
| 71 | + if(stripos($this->msg->header->get('content-type'),'text/')===0){ | ||
| 72 | + $this->parseRawHtml(); | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + /** | ||
| 79 | + * 解析 不是多块级的邮件体 直接就是html或者text的 | ||
| 80 | + * @author:dc | ||
| 81 | + * @time 2024/9/21 11:37 | ||
| 82 | + */ | ||
| 83 | + private function parseRawHtml() { | ||
| 84 | + | ||
| 85 | + $data = $this->parseMimeHeader('Content-Type: '.$this->msg->header->get('content-type')); | ||
| 86 | + | ||
| 87 | + // 设置编码规则 | ||
| 88 | + if($this->msg->header->get('Content-Transfer-Encoding')){ | ||
| 89 | + $data->set('Content-Transfer-Encoding',$this->msg->header->get('Content-Transfer-Encoding')); | ||
| 90 | + } | ||
| 68 | 91 | ||
| 92 | + // 是否是item fetch | ||
| 93 | + if(preg_match('/^\* \d+ FETCH \(/',$this->raw)){ | ||
| 94 | + $body = mb_substr(trim($this->raw),strpos($this->raw,'(')+1,-1); | ||
| 95 | + // 打散成数组 | ||
| 96 | + $body = explode("\r\n",trim($body)); | ||
| 97 | + /***************** start 第一行处理 **************/ | ||
| 98 | + // 第一行 UID 1568602721 RFC822.TEXT {589} | ||
| 99 | + $first = explode(' ',$body[0]); | ||
| 100 | + while (1){ if(str_starts_with(array_shift($first), 'RFC822.')) break; } | ||
| 101 | + $first = array_values($first); | ||
| 102 | + $first[0] = preg_replace("/^\{\d+\}/",'',$first[0]); | ||
| 103 | + // 第一行的结果就是 踢出 UID 1568602721 RFC822.TEXT {589} | ||
| 104 | + $body[0] = implode("\r\n",$first); | ||
| 105 | + /***************** end 第一行处理 **************/ | ||
| 106 | +// ----------------------------------------------------------- | ||
| 107 | + /***************** start 最后一行处理 **************/ | ||
| 108 | + // 最后一行可能是 UID 1568602721 微软的就是 | ||
| 109 | + $end = trim(end($body)); | ||
| 110 | + $end = preg_replace("/(UID \d+)|(FLAGS \([\\a-z* ]*\))/",'',$end); | ||
| 111 | + if(!trim($end)){ array_pop($body); } | ||
| 112 | + /***************** end 最后一行处理 **************/ | ||
| 113 | + | ||
| 114 | + // 再次组装成字符串 | ||
| 115 | + $data->body = trim(implode("\r\n",$body)); | ||
| 116 | + | ||
| 117 | + $this->items[] = $this->bodyDeCode($data); | ||
| 69 | 118 | ||
| 70 | } | 119 | } | 
| 71 | 120 | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + | ||
| 72 | /** | 124 | /** | 
| 73 | * 解析每个 块 | 125 | * 解析每个 块 | 
| 74 | * @param string $body 块字符串 | 126 | * @param string $body 块字符串 | 
| @@ -79,25 +131,35 @@ class Body { | @@ -79,25 +131,35 @@ class Body { | ||
| 79 | protected function parseItem(string $body):DataArray { | 131 | protected function parseItem(string $body):DataArray { | 
| 80 | list($mime_header,$text) = explode("\r\n\r\n",$body,2); | 132 | list($mime_header,$text) = explode("\r\n\r\n",$body,2); | 
| 81 | 133 | ||
| 134 | + // 解析头部 | ||
| 82 | $data = $this->parseMimeHeader($mime_header); | 135 | $data = $this->parseMimeHeader($mime_header); | 
| 83 | 136 | ||
| 137 | + $data->body = $text; | ||
| 138 | + | ||
| 139 | + return $this->bodyDeCode($data); | ||
| 140 | + | ||
| 141 | + } | ||
| 84 | 142 | ||
| 143 | + /** | ||
| 144 | + * @param DataArray $data | ||
| 145 | + * @return DataArray | ||
| 146 | + * @author:dc | ||
| 147 | + * @time 2024/9/21 11:39 | ||
| 148 | + */ | ||
| 149 | + private function bodyDeCode(DataArray $data):DataArray { | ||
| 85 | // 处理body体 的编码 | 150 | // 处理body体 的编码 | 
| 86 | switch ($data->get('Content-Transfer-Encoding')){ | 151 | switch ($data->get('Content-Transfer-Encoding')){ | 
| 87 | case 'quoted-printable':{ | 152 | case 'quoted-printable':{ | 
| 88 | - $text = quoted_printable_decode($text);break; | 153 | + $data->body = quoted_printable_decode($data->body);break; | 
| 89 | } | 154 | } | 
| 90 | case 'base64':{ | 155 | case 'base64':{ | 
| 91 | - $text = base64_decode($text);break; | 156 | + $data->body = base64_decode($data->body);break; | 
| 92 | } | 157 | } | 
| 93 | } | 158 | } | 
| 94 | - | ||
| 95 | - $data->body = $text; | ||
| 96 | - | ||
| 97 | return $data; | 159 | return $data; | 
| 98 | - | ||
| 99 | } | 160 | } | 
| 100 | 161 | ||
| 162 | + | ||
| 101 | /** | 163 | /** | 
| 102 | * 解析邮件体里面的每个块 头部 | 164 | * 解析邮件体里面的每个块 头部 | 
| 103 | * @param string $header | 165 | * @param string $header | 
| @@ -126,11 +188,13 @@ class Body { | @@ -126,11 +188,13 @@ class Body { | ||
| 126 | $contentType = explode(' ',trim(str_replace(';',' ',$data->get('Content-Type')))); | 188 | $contentType = explode(' ',trim(str_replace(';',' ',$data->get('Content-Type')))); | 
| 127 | foreach ($contentType as $ct){ | 189 | foreach ($contentType as $ct){ | 
| 128 | $ct = trim($ct); | 190 | $ct = trim($ct); | 
| 191 | + // 这个才是真的类型 | ||
| 129 | if(str_contains($ct,'/')){ | 192 | if(str_contains($ct,'/')){ | 
| 130 | $data->set('Content-Type',$ct); | 193 | $data->set('Content-Type',$ct); | 
| 131 | }elseif (str_contains($ct,'=')){ | 194 | }elseif (str_contains($ct,'=')){ | 
| 195 | + // 这里包含了其他 | ||
| 132 | list($name,$val) = explode('=',$ct); | 196 | list($name,$val) = explode('=',$ct); | 
| 133 | - $data->set($name,trim($val)); | 197 | + $data->set($name,trim(str_replace('"','',$val))); | 
| 134 | } | 198 | } | 
| 135 | } | 199 | } | 
| 136 | } | 200 | } | 
| @@ -168,9 +232,10 @@ class Body { | @@ -168,9 +232,10 @@ class Body { | ||
| 168 | public function getHtml():string { | 232 | public function getHtml():string { | 
| 169 | foreach ($this->items as $item){ | 233 | foreach ($this->items as $item){ | 
| 170 | if($item->eq('content-type','text/html')){ | 234 | if($item->eq('content-type','text/html')){ | 
| 171 | - return $item->body; | 235 | + return $item->body ? : ''; | 
| 172 | } | 236 | } | 
| 173 | } | 237 | } | 
| 238 | + return ''; | ||
| 174 | } | 239 | } | 
| 175 | 240 | ||
| 176 | /** | 241 | /** | 
- 
请 注册 或 登录 后发表评论
