Ciao a tutti raga,
ho visto che questo argomento è stato più volte oggetto di discussione, ma dato che non c'è niente di concreto, ho pensato di scrivere questa piccolissima PILLOLA che spiega come leggere le E-mail utilizzando l'estensione IMAP.
Prima di cominciare premetto che non sono un bravo programmatore (lavoro con php da solo 5 mesi) quindi sono sicuro che il codice postato possa essere scritto meglio (infatti se c'è qualcuno che lo vuole migliorare è bene accetto
)
Fatta questa piccolissima (ma doverosa) premessa, siamo pronti per iniziare.
1) Innanzitutto attiviamo la libreria IMAP:
-verifichiamo che sia presente nella cartella EXTENSIONS del php la relativa php_imap.dll;
-quindi decommentiamo nel php.ini la seguente riga:
;extension=php_imap.dll (ossia eliminiamo il ; )
Installata correttamente la libreria possiamo iniziare a creare la nostra web-mail.
2)creiamo una cartella (che io ho chiamato Formail) contenente i seguenti file
- index.htm;
- config.php;
- lista.php;
- view.php;
- allegato.php;
- struttura.php;
- seleziona.php;
3) index.htm
questa pagina serve per avere due frameset:
in quello di sinistra avremo la lista completa di tutte le E-mail ricevute;
in quello di destra verrà visualizzata l'E-mail selezionato.
Copiateci il seguente codice:
codice:
<html>
<head>
<title>::. FORMAIL V:1.0 .::</title>
</head>
<frameset cols="750,*">
<frame name="sinistra" src="lista.php">
<frame name="destra" src="seleziona.php">
<noframes>
<body>
La pagina corrente utilizza i frame. Questa caratteristica non è supportata
dal browser in uso.</p>
</body>
</noframes>
</frameset>
</html>
4) config.php
inserite questo codice:
Codice PHP:
<?php
$server = "mail.tuoserver.it";
$utente = "tua@email.it";
$pass = "tuapassword";
$mbox = imap_open("{".$server.":110/pop3}INBOX", $utente, $pass);
?>
Con questa pagina in pratica stabiliamo una connessione con il server POP3 che contiene le nostre E-mail. (penso che ci sia poco da dover spiegare);
5) lista.php
inserite questo codice:
Codice PHP:
<?php
include_once("config.php");
echo "<h1>Posta in arrivo</h1>\n<TABLE width=700>
<TR><TD width=200><FONT COLOR=RED>[B]MITTENTE:[/B]</FONT></TD><TD with=400><FONT COLOR=RED>[B]OGGETTO:[/B]</FONT></TD>
<TD with=100><FONT COLOR=RED>[B]STRUTTURA:[/B]</FONT></TD></TR>";
$headers = imap_headers($mbox);
$a = "0";
if ($headers == false) {
echo "La cartella 'POSTA IN ARRIVO' è vuota!
\n";
} else {
while (list ($key, $val) = each ($headers)) {
$a = $a+1;
$overview = imap_fetch_overview($mbox, $a, 0);
while(list($key, $value) = each($overview)){
echo "<td bgcolor=#DDDDDD>".$value->from."</td>
<td bgcolor=#DDDDDD><a href=view.php?a=".$a." target=destra>[b]".$value->subject."[/b]</a></TD>
<td bgcolor=#DDDDDD><a href=struttura.php?a=".$a." target=destra>[b]struttura[/b]</a></TD></TR>\n";
}
}
}
echo "</TABLE>";
imap_close($mbox);
?>
tramite la funzione imap_headers($mbox); andiamo a leggere appunto gli headers di tutte le E-mail e quindi:
- soggetto;
- mittente;
...
e applichiamo un ciclo per leggerle tutte.
La variabile $a identifica l'E-mail di cui stiamo leggendo l'headers e verrà poi passata alla pagina view per leggerne il contenuto (solo di quella E-mail specifica).
In questo momento se provate a richiamare dal localhost la vostra Formail dovreste già visualizzare l'elenco di tutte l'E-mail che avete ricevuto! Figo no?!
6) view.php
inserite questo codice:
Codice PHP:
<?php
if (isset($_GET['a']))
$a = $_GET['a'];
include_once("config.php");
$struct = imap_fetchstructure($mbox, $a);
$e = "0";
$j = "";
$assegnato = false;
$modifica=false;
$ipertesti=false;
foreach($struct as $k => $valore) {
if (!$assegnato AND $k=="subtype") {
if ($valore=="RELATED"){
$j = ".2";
$assegnato=true;
}
if ($valore=="MIXED"){
$j = ".2";
$assegnato=true;
$modifica=true; //se ci sono allegati deve essere stampata la prima parte dell'E-mail (il testo)
echo "<TABLE width=100%><TR><TD bgcolor=#eeeeee align=right><FONT COLOR=RED size=2pt>[B]ALLEGATI:</font>";
}
}
if ($k=="parts") {
$parti = $struct -> parts;
foreach($parti as $k0 => $valore0) {
$e = $e+1;
foreach($valore0 as $k1 => $valore1){
//////VERIFICo SE CI SONO ALLEGATI/////////////////////////////////////////////
if ($k1=="disposition" AND $valore1=="ATTACHMENT"){
$allegato = $struct -> parts[$e-1] -> dparameters[0] -> value;
echo "[B][url="allegato.php?a=$a&parte=$e"]".$allegato."[/url]";
}
////////////////////////////////////////////////////////////////////////////////
}
}
}
}
if ($e=="0") {
$e = 1;
echo "<PRE>";
$ipertesti=true;
}
if ($modifica){
$e=1;
echo "[/B]</TD></TR></TABLE><HR>";
}
$frase=imap_fetchbody($mbox, $a, $e.$j);
$frase=quoted_printable_decode(str_replace("=\r\n","",$frase));
if (!$ipertesti) {
echo $frase;
} else {
///////////////SERVE PER RICONOSCERE ED ATTIVARE GLI IPERTESTI(non è necessario però è utile!)/////////////
$parole="";
$righe = explode("\n", $frase);
for ($z=0;$z<sizeof($righe);$z++)
{
$righe[$z] = $righe[$z]."
";
$parole=array_merge($parole,explode(" ", $righe[$z]));
}
for ($key=0;$key<sizeof($parole);$key++)
{
$http = strpos($parole[$key], "http");
$href = strpos($parole[$key], "href");
$www = strpos($parole[$key], "www");
if ($href === false) {
if ($http === false AND $www === false) {
echo $parole[$key]." ";
} else {
echo " [url='".str_replace(']".$parole[$key]."[/url] ";
}
} else {
echo $parole[$key]." ";
}
}
}
imap_close($mbox);
?>
questo è il vero cuore di tutta la PILLOLA.
le seguenti variabili dichiarate:
$e = "0";
$j = "";
$assegnato = false;
$modifica=false;
$ipertesti=false;
servono per non visualizzare i notice;
Dapprima creo l'array $struct con la funzione imap_fetchstructure($mbox, $a);
quindi tramite un foreach ne esploro il contenuto.
Questo serve per capire come è strutturata l'E-mail specifica e quindi come decodificarla per poterla leggere correttamente.
Infatti le E-mail possono essere costituite da più parti (una scritta, una contenente un allegato, una in formato html) e di ogni parte viene specificata:
la codifica;
la dimensione;
il formato;
se contiene un allegato;
....
per capire meglio quello che ho appena detto ho realizzato un'altra pagina: struttura.php che visualizza l'elenco di tutte le sotto parti dell'E-mail (serve solo a scopo di chiarimento e lo vedremo dopo)
Tornando a noi:
viene dapprima verifato se la variabile subtype è di tipo RELATED o MIXED perchè queste particolari E-mail vengono lette in modo diverso
(ossia viene assegnato a $j il valore .2
Inoltre un' E-mail è di tipo MIXED quando contiene un allegato.
In tal caso la parte che contiene il testo dell'E-mail è la prima, mentre quelle successive contengono ciascuna un allegato (non so se è sempre così, però nel mio caso, le ho trovate tutte strutturate in questo modo).
E' ovvio quindi che la parte da dover stampare a video è la prima, quini assegno alla variabile $e il valore 1.
Quando c'è un allegato la variabile disposition (relativa alla parte dell'E-mail in cui c'è l'allegato) assume il seguente valore: ATTACHAMENT.
Finalmente, capito com'è strutturata la nostra E-mail, siamo in grado di leggerla utilizzando questa funzione:
$frase=imap_fetchbody($mbox, $a, $e.$j);
dove $e indica la parte contenente il testo html che deve essere stampata che di norma è l'ultima. (tranne come abbiamo visto prima in quelle di tipo MIXED)
Va fatta però una specificazione per l'E-mail che hanno solo una parte. In tal caso la variabile $e (che non viene mai incrementata) deve essere portata al valore 1, altrimenti andremmo a leggere la parte 0.
la seguente funzione invece serve per decifrare tutti i caratteri particolari (tipo: =20 =80 ecc.)
$frase=quoted_printable_decode(str_replace("=\r\n" ,"",$frase));
A questo punto possiamo stampare la nostra E-mail effettuando un semplice echo $frase;
Tuttavia ci sono dei casi in cui l'E-mail anzichè essere di tipo html è di tipo Plan (ossia semplice testo) quindi perderemmo la formattazione ed i collegamenti ipertestuali.
Per la formattazione basta usare il tag <PRE>;
mentre per attivare i collegamenti ho creato una funzione che esplode il corpo del messaggio dove sono presenti spazi e invii (" ", "\n") ottenendo quindi un array costituito da tutte le parole del messaggio.
Quindi verifica se all'interno di una parola sia presente la stringa "href", "www", "http" in tal caso trasforma quella parola in un ipertesto.
mbè non era complicato però mi sa che mi sono spiegato malissimo sperò comunque che abbiate capito, altrimenti rileggete!
7) allegato.php
inserite questo codice:
Codice PHP:
<?php
if (isset($_GET['a']))
$a = $_GET['a'];
if (isset($_GET['parte']))
$parte = $_GET['parte'];
include_once("config.php");
echo base64_decode(imap_fetchbody($mbox, $a, $parte));
imap_close($mbox);
?>
Come potete vedere è veramente semplice, in pratica viene effettuata una decodifica a 64bit nella parte dell'E-mail contenente l'allegato e stampata.
8) struttura.php
inserite questo codice:
Codice PHP:
<?php
if (isset($_GET['a']))
$a = $_GET['a'];
include_once("config.php");
$struct = imap_fetchstructure($mbox, $a);
$e="0";
echo "
<FONT COLOR=BLUE>[B]Struttura E-mail:[/B]</FONT>
";
foreach($struct as $k => $valore) {
if ($k!="parts") {
echo $k." = ".$valore."
";
} else {
echo "[b]PARTS:[/B]
";
$parti = $struct -> parts;
foreach($parti as $k0 => $valore0) {
$e = $e+1;
echo "<FONT COLOR=RED>[B]".$e."----------------[/B]
</FONT>";
foreach($valore0 as $k1 => $valore1){
if ($k1!="dparameters"){
echo $k1." = ".$valore1."
";
} else {
echo "<FONT COLOR=BLUE>dparameters</FONT>
";
$dparameters = $struct -> parts[$e-1] -> dparameters[0];
foreach($dparameters as $k10 => $valore10){
echo $k10." = ".$valore10."
";
}
echo "<FONT COLOR=BLUE>FINE dparameters</FONT>
";
}
}
}
}
}
imap_close($mbox);
?>
Come ho già accennato prima questa pagina serve solo a scopo di chiarimento, in pratica stampa il contenuto dell'array $struct.
9) seleziona.php
potete lasciarlo vuoto
10) Saluti
Ok, siamo arrivati alla conclusione, spero che possa essere di aiuto a qualcuno e che venga inserite tra le altre PILLOLE.
Vi ricordo che potete migliorare il codice (che è veramente pessimo)
però postatelo in modo da farmi vedere cosa c'è di sbagliato.
Io l'ho testato con una trentina di E-mail ed ha sempre funzionato tuttavia se dovesse esserci qualche bug o qualcuno riscontrasse qualche problema: segnalatelo!
mbè vi saluto lasciandovi però con questo piccolo chiarimento:
se per scaricare tutte le E-mail occorrono più di 30 secondi appare un bel errore fatale