我正在使用以下功能从现有imap连接($ imap)上的电子邮件(索引为$ m)获取附件
function parse_parts(&$structure, &$attachments, &$imap, $m, $par){
if(isset($structure->parts) && count($structure->parts) ) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
$lstk= array_keys($attachments); $j=end($lstk); // use this instead of $i to avoid overlapping indices when there's sub-parts and recursion
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$j]['is_attachment'] = true;
$attachments[$j]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$j]['is_attachment'] = true;
$attachments[$j]['filename'] = imap_utf8($object->value);
}
}
}
if($attachments[$j]['is_attachment']) {
if($par==''){
$attachments[$j]['attachment'] = imap_fetchbody($imap, $m, $i+1);
}else{
$attachments[$j]['attachment'] = imap_fetchbody($imap, $m, $par . $i+1);
}
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$j]['attachment'] = base64_decode($attachments[$j]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$j]['attachment'] = quoted_printable_decode($attachments[$j]['attachment']);
}else{echo "encod:". $structure->parts[$i]->encoding . PHP_EOL; }
}
if(isset($structure->parts[$i]->parts) && count($structure->parts[$i]->parts)){ //if the part contains its own parts, recurse
$prnt = $i;
$prnt = $prnt . '.';
parse_parts($structure->parts[$i], $attachments, $imap, $m, $prnt );
}
}
}
}
稍后调用此函数的函数如下:
$structure = imap_fetchstructure($imap, $m);
$attachments = array();
parse_parts($structure, $attachments, $imap, $m, '');
标准函数可以正常工作,但是当它必须递归时(即有嵌套的部分),虽然看起来确实是正确的大小,但生成的文件不可读。知道我在做什么错吗? 我尝试将$ prnt更改为
$prnt = $i+1 .'.';
但是,它只是输出一个空文件。 我注意到其他人在这里也有类似的问题: imap - get attached file
但他们的解决方案似乎不适用于此电子邮件/代码。
答案 0 :(得分:0)
感谢IVO GELOV发现我的错误。最终工作功能:
function parse_parts(&$structure, &$attachments, &$imap, $m, $par){
if(isset($structure->parts) && count($structure->parts) ) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
$lstk= array_keys($attachments); $j=end($lstk); // use this instead of $i to avoid overlapping indices when there's sub-parts and recursion
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$j]['is_attachment'] = true;
$attachments[$j]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$j]['is_attachment'] = true;
$attachments[$j]['filename'] = imap_utf8($object->value);
}
}
}
if($attachments[$j]['is_attachment']) {
if($par==''){
$attachments[$j]['attachment'] = imap_fetchbody($imap, $m, ($i+1));
}else{
$attachments[$j]['attachment'] = imap_fetchbody($imap, $m, $par . ($i+1));
}
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$j]['attachment'] = base64_decode($attachments[$j]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$j]['attachment'] = quoted_printable_decode($attachments[$j]['attachment']);
}else{echo "encod:". $structure->parts[$i]->encoding . PHP_EOL; }
}
if(isset($structure->parts[$i]->parts) && count($structure->parts[$i]->parts)){ //if the part contains its own parts, recurse
$prnt = $i+1;
$prnt = $prnt . '.';
parse_parts($structure->parts[$i], $attachments, $imap, $m, $prnt );
}
}
}
}
答案 1 :(得分:0)
附件也可以是内联文件或外部文件。
所以我们必须同时获得两种附件。
$structure = imap_fetchstructure($this->imap, $id);
$fileName = $attachments = array();
/* if any attachments found... */
if (isset($structure->parts) && count($structure->parts)) {
$n = 0;
for($i = 0; $i < count($structure->parts); $i++){
if(isset($structure->parts[$i]->parts) && !empty($structure->parts[$i]->parts) && count($structure->parts[$i]->parts)>0){
for($y = 0; $y < count($structure->parts[$i]->parts); $y++)
{
$attachments[$n] = array('is_attachment' => false,'filename' => '','name' => '','attachment' => '','size' => '','cid' => 0);
if($structure->parts[$i]->parts[$y]->ifdparameters==1) {
foreach($structure->parts[$i]->parts[$y]->dparameters as $object){
if(strtolower($object->attribute) == 'filename'){
$attachments[$n]['is_attachment'] = true;
$fileName[0] = $object->value;
$filename = $this->filterFileName($fileName);
$attachments[$n]['filename'] = $filename;
$attachments[$n]['name'] = $filename;
}
}
}
if($structure->parts[$i]->parts[$y]->ifparameters){
foreach($structure->parts[$i]->parts[$y]->parameters as $object){
if(strtolower($object->attribute) == 'name'){
$attachments[$n]['is_attachment'] = true;
$fileName[0] = $object->value;
$filename = $this->filterFileName($fileName);
$attachments[$n]['name'] = $filename;
$attachments[$n]['filename'] = $filename;
}
}
}
if($attachments[$n]['is_attachment']){
$attachments[$n]['attachment'] = imap_fetchbody($this->imap, $id, ($i+1).'.'.($y+1));
if($structure->parts[$i]->parts[$y]->encoding == 3){ /* 4 = QUOTED-PRINTABLE encoding */
$attachments[$n]['attachment'] = base64_decode($attachments[$n]['attachment']);
}
elseif($structure->parts[$i]->parts[$y]->encoding == 4){ /* 3 = BASE64 encoding */
$attachments[$n]['attachment'] = quoted_printable_decode($attachments[$n]['attachment']);
}
$attachments[$n]['size'] = $structure->parts[$i]->parts[$y]->bytes;
$attachments[$n]['cid'] = ($structure->parts[$i]->parts[$y]->ifid) ? str_replace(array('<', '>'), '', $structure->parts[$i]->parts[$y]->id) : 0;
}
$email['attachments'][] = $attachments[$n];$n++;
}
}else{
$attachments[$n] = array('is_attachment' => false,'filename' => '','name' => '','attachment' => '','size' => '','cid' => 0);
if($structure->parts[$i]->ifdparameters==1){
foreach($structure->parts[$i]->dparameters as $object){
if(strtolower($object->attribute) == 'filename'){
$attachments[$n]['is_attachment'] = true;
$fileName[0] = $object->value;
$filename = $this->filterFileName($fileName);
$attachments[$n]['filename'] = $filename;
$attachments[$n]['name'] = $filename;
}
}
}
if($structure->parts[$i]->ifparameters){
foreach($structure->parts[$i]->parameters as $object){
if(strtolower($object->attribute) == 'name'){
$attachments[$n]['is_attachment'] = true;
$fileName[0] = $object->value;
$filename = $this->filterFileName($fileName);
$attachments[$n]['name'] = $filename;
$attachments[$n]['filename'] = $filename;
}
}
}
if($attachments[$n]['is_attachment']){
$attachments[$n]['attachment'] = imap_fetchbody($this->imap, $id, $i+1);
if($structure->parts[$i]->encoding == 3){/* 4 = QUOTED-PRINTABLE encoding */
$attachments[$n]['attachment'] = base64_decode($attachments[$n]['attachment']);
}elseif($structure->parts[$i]->encoding == 4){ /* 3 = BASE64 encoding */
$attachments[$n]['attachment'] = quoted_printable_decode($attachments[$n]['attachment']);
}
$attachments[$n]['size'] = $structure->parts[$i]->bytes;
$attachments[$n]['cid'] = ($structure->parts[$i]->ifid) ? str_replace(array('<', '>'), '', $structure->parts[$i]->id) : 0;
}
$email['attachments'][] = $attachments[$n];$n++;
}
}
}
public function filterFileName($fileName) {
$newstr = preg_replace('/[^a-zA-Z0-9\-\.\']/', '_', $fileName[0]);
$fileName = str_replace("'", '', $newstr);
return $fileName;
}
之后,您必须存储此附件