recupération pièces jointes multiples via imap_open et file_put_contents

Petit nouveau ! | 7 Messages

28 mai 2022, 14:04

Bonjour,
J'ai réussi a implémenté un petit script php qui se connecte sur une boite mail récupère une pièce jointe d'un mail, l'enregistre dans le dossier d'où est lancé le script et efface le mail.
Jusqu’ici tout va bien, mais j'ai besoin que le script récupère Les 2 pièces jointes quand il y en a 2.
Et là je ne sais pas du tout comment faire et je ne sais même pas si c'est possible.
Merci donc de m'aiguiller.
Mon script actuel est un peu bavard mais pour le moment c'est volontaire. Je précise que je bafouille le php plus que je le parle :oops:

Code : Tout sélectionner

$imap = imap_open($server, $username, $password) or die("imap connection error"); $message_count = imap_num_msg($imap); for ($m = 1; $m <= $message_count; ++$m) { $header = imap_headerinfo($imap, $m); //print_r($header); $email[$m]['from'] = $header->from[0]->mailbox.'@'.$header->from[0]->host; $email[$m]['fromaddress'] = $header->from[0]->personal; $email[$m]['to'] = $header->to[0]->mailbox; $email[$m]['subject'] = $header->subject; $email[$m]['message_id'] = $header->message_id; $email[$m]['date'] = $header->udate; $from = $email[$m]['fromaddress']; $from_email = $email[$m]['from']; $to = $email[$m]['to']; $subject = $email[$m]['subject']; $structure = imap_fetchstructure($imap, $m); $attachments = array(); if(isset($structure->parts) && count($structure->parts)) { for($i = 0; $i < count($structure->parts); $i++) { $attachments[$i] = array( 'is_attachment' => false, 'filename' => '', 'name' => '', 'attachment' => '' ); if($structure->parts[$i]->ifdparameters) { foreach($structure->parts[$i]->dparameters as $object) { if(strtolower($object->attribute) == 'filename') { $attachments[$i]['is_attachment'] = true; $attachments[$i]['filename'] = $object->value; } } } if($structure->parts[$i]->ifparameters) { foreach($structure->parts[$i]->parameters as $object) { if(strtolower($object->attribute) == 'name') { $attachments[$i]['is_attachment'] = true; $attachments[$i]['name'] = $object->value; } } } if($attachments[$i]['is_attachment']) { $attachments[$i]['attachment'] = imap_fetchbody($imap, $m, $i+1); if($structure->parts[$i]->encoding == 3) { // 3 = BASE64 $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']); } elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']); } } } } foreach ($attachments as $key => $attachment) { $name = $attachment['name']; $contents = $attachment['attachment']; } echo "Expéditeur : " .$from_email . "<br />\n"; echo "Sujet : " .$subject . "<br />\n"; echo "Pièce jointe : " .$name . "<br />\n"; file_put_contents($name, $contents); echo "Pièce jointe : " .$name . '</br>'; } $check = imap_mailboxmsginfo($imap); echo "Nombre de messages avant effacement : " . $check->Nmsgs . "<br />\n"; imap_delete($imap, 1); $check = imap_mailboxmsginfo($imap); echo "Nombre de messages après effacement : " . $check->Nmsgs . "<br />\n"; imap_expunge($imap,); $check = imap_mailboxmsginfo($imap); echo "Nombre de messages après imap_expunge : " . $check->Nmsgs . "<br />\n"; $check = imap_mailboxmsginfo($imap); echo "Nombre de messages avant effacement : " . $check->Nmsgs . "<br />\n"; imap_delete($imap, 1); $check = imap_mailboxmsginfo($imap); echo "Nombre de messages après effacement : " . $check->Nmsgs . "<br />\n"; imap_expunge($imap,); $check = imap_mailboxmsginfo($imap); echo "Nombre de messages après imap_expunge : " . $check->Nmsgs . "<br />\n"; imap_close($imap);

Mammouth du PHP | 2703 Messages

28 mai 2022, 14:31

mettre
file_put_contents($name, $contents);
dans le foreach
foreach ($attachments as $key => $attachment) {
et non après

Petit nouveau ! | 7 Messages

28 mai 2022, 18:35

Ok merci encore, mais celà n'a réglé que partiellement mon soucis. Effectivement en déplaçant file_put_contents dans le foreach{} je traite bien 2 mails à la fois mais je ne traite toujours qu'une seule pièce jointe par mail ce qui était mon soucis de base.
Il y a d'ailleurs un problème dans la façon dont mon code liste et compte les pièces jointes car je n'en voit toujours qu'une seule. Alors qu'il est sensé trouver un fichier .jpg et un fichier .txt.
J'ai l'impression que c'est du côté de imap_fetchstructure que je ne suis pas au point. Si quelqu'un peut m'aider, je suis preneur .

Merci d'avance

Petit nouveau ! | 7 Messages

04 juin 2022, 12:40

Bonjours à tous,
Après bien des tentatives et bien des échecs, j'ai enfin réussi à lister et surtout détacher mes 2 pièces jointes pour les enregistrer sur le serveur.
Il m'a fallu rajouter un

Code : Tout sélectionner

if($name)
dans le

Code : Tout sélectionner

foreach ($attachments as $i => $attachment){}
pour que les 2 fichiers soient bien enregistrés
L'ensemble du code est donc

Code : Tout sélectionner

foreach ($attachments as $i => $attachment) { $name = $attachment['name']; $contents = $attachment['attachment']; echo "Pièce jointe : " .$name. "<br />\n"; echo "valeur key : " .$i. "<br />\n"; if($name) {file_put_contents($name,$contents);} }
Pour ceux qui seraient intéressés, Je vous livre l'ensemble du code qui fonctionne sous PHP 8.0.19

Code : Tout sélectionner

<?php //ouvre inbox listing messages et copie pièces jointes multiples $server="{serveur:port/tls}INBOX"; // connection au dossier inbox de la mailbox $username="nom_utilisateur"; //imap login $password="mot_de_passe"; //imap password $imap = imap_open($server, $username, $password) or die("imap connection error"); $message_count = imap_num_msg($imap); for ($m = 1; $m <= $message_count; ++$m) { $header = imap_headerinfo($imap, $m); //print_r($header); $email[$m]['from'] = $header->from[0]->mailbox.'@'.$header->from[0]->host; $email[$m]['fromaddress'] = $header->from[0]->personal; $email[$m]['to'] = $header->to[0]->mailbox; $email[$m]['subject'] = $header->subject; $email[$m]['message_id'] = $header->message_id; $email[$m]['date'] = $header->udate; $from = $email[$m]['fromaddress']; $from_email = $email[$m]['from']; $to = $email[$m]['to']; $subject = $email[$m]['subject']; $structure = imap_fetchstructure($imap, $m); $attachments = array(); if (isset($structure->parts) && count($structure->parts)) { for ($i = 0; $i < count($structure->parts); $i++) { $attachments[$i] = array( 'is_attachment' => false, 'filename' => '', 'name' => '', 'attachment' => ''); if ($structure->parts[$i]->ifdparameters) { foreach($structure->parts[$i]->dparameters as $object) { if(strtolower($object->attribute) == 'filename') { $attachments[$i]['is_attachment'] = true; $attachments[$i]['filename'] = $object->value; } } } if ($structure->parts[$i]->ifparameters) { foreach($structure->parts[$i]->parameters as $object) { if(strtolower($object->attribute) == 'name') { $attachments[$i]['is_attachment'] = true; $attachments[$i]['name'] = $object->value; } } } if ($attachments[$i]['is_attachment']) { $attachments[$i]['attachment'] = imap_fetchbody($imap, $m, $i+1); if($structure->parts[$i]->encoding == 3) { // 3 = BASE64 $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']); } elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']); } } } foreach ($attachments as $i => $attachment) { $name = $attachment['name']; $contents = $attachment['attachment']; echo "Pièce jointe : " .$name. "<br />\n"; echo "valeur key : " .$i. "<br />\n"; if($name) {file_put_contents($name,$contents);} } } } $check = imap_mailboxmsginfo($imap); echo "Nombre de messages avant effacement : " . $check->Nmsgs . "<br />\n"; imap_close($imap); ?>
Comme je l'avais indiqué, je suis loin de parler et d'écrire courament le PHP, il est fort probable que ce code puisse être optimisé. Si vous avez des idées n'hésitez pas à commenter et me donnez vos avis.
Merci d'avance

Eléphanteau du PHP | 19 Messages

17 mai 2024, 14:59

Bonjour abmag,

ton post m'interesse fortement , je travaille actuellement sur l'affichage des mails , cela fonctionne bien , et je cherchais également comme toi à afficher et a enregistrer les pièces jointes .

par contre je n'arrive pas a lier ton code au mien .

pourrais tu m'aider ?

merci